1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.lang3;
18
19 import java.lang.reflect.Array;
20 import java.util.Arrays;
21 import java.util.BitSet;
22 import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.apache.commons.lang3.builder.EqualsBuilder;
27 import org.apache.commons.lang3.builder.HashCodeBuilder;
28 import org.apache.commons.lang3.builder.ToStringBuilder;
29 import org.apache.commons.lang3.builder.ToStringStyle;
30 import org.apache.commons.lang3.math.NumberUtils;
31 import org.apache.commons.lang3.mutable.MutableInt;
32
33 /**
34 * <p>Operations on arrays, primitive arrays (like {@code int[]}) and
35 * primitive wrapper arrays (like {@code Integer[]}).</p>
36 *
37 * <p>This class tries to handle {@code null} input gracefully.
38 * An exception will not be thrown for a {@code null}
39 * array input. However, an Object array that contains a {@code null}
40 * element may throw an exception. Each method documents its behaviour.</p>
41 *
42 * <p>#ThreadSafe#</p>
43 * @since 2.0
44 * @version $Id$
45 */
46 public class ArrayUtils {
47
48 /**
49 * An empty immutable {@code Object} array.
50 */
51 public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
52 /**
53 * An empty immutable {@code Class} array.
54 */
55 public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
56 /**
57 * An empty immutable {@code String} array.
58 */
59 public static final String[] EMPTY_STRING_ARRAY = new String[0];
60 /**
61 * An empty immutable {@code long} array.
62 */
63 public static final long[] EMPTY_LONG_ARRAY = new long[0];
64 /**
65 * An empty immutable {@code Long} array.
66 */
67 public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
68 /**
69 * An empty immutable {@code int} array.
70 */
71 public static final int[] EMPTY_INT_ARRAY = new int[0];
72 /**
73 * An empty immutable {@code Integer} array.
74 */
75 public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
76 /**
77 * An empty immutable {@code short} array.
78 */
79 public static final short[] EMPTY_SHORT_ARRAY = new short[0];
80 /**
81 * An empty immutable {@code Short} array.
82 */
83 public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
84 /**
85 * An empty immutable {@code byte} array.
86 */
87 public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
88 /**
89 * An empty immutable {@code Byte} array.
90 */
91 public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
92 /**
93 * An empty immutable {@code double} array.
94 */
95 public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
96 /**
97 * An empty immutable {@code Double} array.
98 */
99 public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
100 /**
101 * An empty immutable {@code float} array.
102 */
103 public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
104 /**
105 * An empty immutable {@code Float} array.
106 */
107 public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
108 /**
109 * An empty immutable {@code boolean} array.
110 */
111 public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
112 /**
113 * An empty immutable {@code Boolean} array.
114 */
115 public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
116 /**
117 * An empty immutable {@code char} array.
118 */
119 public static final char[] EMPTY_CHAR_ARRAY = new char[0];
120 /**
121 * An empty immutable {@code Character} array.
122 */
123 public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
124
125 /**
126 * The index value when an element is not found in a list or array: {@code -1}.
127 * This value is returned by methods in this class and can also be used in comparisons with values returned by
128 * various method from {@link java.util.List}.
129 */
130 public static final int INDEX_NOT_FOUND = -1;
131
132 /**
133 * <p>ArrayUtils instances should NOT be constructed in standard programming.
134 * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
135 *
136 * <p>This constructor is public to permit tools that require a JavaBean instance
137 * to operate.</p>
138 */
139 public ArrayUtils() {
140 super();
141 }
142
143
144 // NOTE: Cannot use {@code} to enclose text which includes {}, but <code></code> is OK
145
146
147 // Basic methods handling multi-dimensional arrays
148 //-----------------------------------------------------------------------
149 /**
150 * <p>Outputs an array as a String, treating {@code null} as an empty array.</p>
151 *
152 * <p>Multi-dimensional arrays are handled correctly, including
153 * multi-dimensional primitive arrays.</p>
154 *
155 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
156 *
157 * @param array the array to get a toString for, may be {@code null}
158 * @return a String representation of the array, '{}' if null array input
159 */
160 public static String toString(final Object array) {
161 return toString(array, "{}");
162 }
163
164 /**
165 * <p>Outputs an array as a String handling {@code null}s.</p>
166 *
167 * <p>Multi-dimensional arrays are handled correctly, including
168 * multi-dimensional primitive arrays.</p>
169 *
170 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
171 *
172 * @param array the array to get a toString for, may be {@code null}
173 * @param stringIfNull the String to return if the array is {@code null}
174 * @return a String representation of the array
175 */
176 public static String toString(final Object array, final String stringIfNull) {
177 if (array == null) {
178 return stringIfNull;
179 }
180 return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
181 }
182
183 /**
184 * <p>Get a hash code for an array handling multi-dimensional arrays correctly.</p>
185 *
186 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
187 *
188 * @param array the array to get a hash code for, {@code null} returns zero
189 * @return a hash code for the array
190 */
191 public static int hashCode(final Object array) {
192 return new HashCodeBuilder().append(array).toHashCode();
193 }
194
195 /**
196 * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
197 * correctly.</p>
198 *
199 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
200 *
201 * @param array1 the left hand array to compare, may be {@code null}
202 * @param array2 the right hand array to compare, may be {@code null}
203 * @return {@code true} if the arrays are equal
204 * @deprecated this method has been replaced by {@code java.util.Objects.deepEquals(Object, Object)} and will be
205 * removed from future releases.
206 */
207 @Deprecated
208 public static boolean isEquals(final Object array1, final Object array2) {
209 return new EqualsBuilder().append(array1, array2).isEquals();
210 }
211
212 // To map
213 //-----------------------------------------------------------------------
214 /**
215 * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
216 * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
217 * elements, where the first element is used as key and the second as
218 * value.</p>
219 *
220 * <p>This method can be used to initialize:</p>
221 * <pre>
222 * // Create a Map mapping colors.
223 * Map colorMap = MapUtils.toMap(new String[][] {{
224 * {"RED", "#FF0000"},
225 * {"GREEN", "#00FF00"},
226 * {"BLUE", "#0000FF"}});
227 * </pre>
228 *
229 * <p>This method returns {@code null} for a {@code null} input array.</p>
230 *
231 * @param array an array whose elements are either a {@link java.util.Map.Entry} or
232 * an Array containing at least two elements, may be {@code null}
233 * @return a {@code Map} that was created from the array
234 * @throws IllegalArgumentException if one element of this Array is
235 * itself an Array containing less then two elements
236 * @throws IllegalArgumentException if the array contains elements other
237 * than {@link java.util.Map.Entry} and an Array
238 */
239 public static Map<Object, Object> toMap(final Object[] array) {
240 if (array == null) {
241 return null;
242 }
243 final Map<Object, Object> map = new HashMap<Object, Object>((int) (array.length * 1.5));
244 for (int i = 0; i < array.length; i++) {
245 final Object object = array[i];
246 if (object instanceof Map.Entry<?, ?>) {
247 final Map.Entry<?,?> entry = (Map.Entry<?,?>) object;
248 map.put(entry.getKey(), entry.getValue());
249 } else if (object instanceof Object[]) {
250 final Object[] entry = (Object[]) object;
251 if (entry.length < 2) {
252 throw new IllegalArgumentException("Array element " + i + ", '"
253 + object
254 + "', has a length less than 2");
255 }
256 map.put(entry[0], entry[1]);
257 } else {
258 throw new IllegalArgumentException("Array element " + i + ", '"
259 + object
260 + "', is neither of type Map.Entry nor an Array");
261 }
262 }
263 return map;
264 }
265
266 // Generic array
267 //-----------------------------------------------------------------------
268 /**
269 * <p>Create a type-safe generic array.</p>
270 *
271 * <p>The Java language does not allow an array to be created from a generic type:</p>
272 *
273 * <pre>
274 public static <T> T[] createAnArray(int size) {
275 return new T[size]; // compiler error here
276 }
277 public static <T> T[] createAnArray(int size) {
278 return (T[])new Object[size]; // ClassCastException at runtime
279 }
280 * </pre>
281 *
282 * <p>Therefore new arrays of generic types can be created with this method.
283 * For example, an array of Strings can be created:</p>
284 *
285 * <pre>
286 String[] array = ArrayUtils.toArray("1", "2");
287 String[] emptyArray = ArrayUtils.<String>toArray();
288 * </pre>
289 *
290 * <p>The method is typically used in scenarios, where the caller itself uses generic types
291 * that have to be combined into an array.</p>
292 *
293 * <p>Note, this method makes only sense to provide arguments of the same type so that the
294 * compiler can deduce the type of the array itself. While it is possible to select the
295 * type explicitly like in
296 * <code>Number[] array = ArrayUtils.<Number>toArray(Integer.valueOf(42), Double.valueOf(Math.PI))</code>,
297 * there is no real advantage when compared to
298 * <code>new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}</code>.</p>
299 *
300 * @param <T> the array's element type
301 * @param items the varargs array items, null allowed
302 * @return the array, not null unless a null array is passed in
303 * @since 3.0
304 */
305 public static <T> T[] toArray(final T... items) {
306 return items;
307 }
308
309 // Clone
310 //-----------------------------------------------------------------------
311 /**
312 * <p>Shallow clones an array returning a typecast result and handling
313 * {@code null}.</p>
314 *
315 * <p>The objects in the array are not cloned, thus there is no special
316 * handling for multi-dimensional arrays.</p>
317 *
318 * <p>This method returns {@code null} for a {@code null} input array.</p>
319 *
320 * @param <T> the component type of the array
321 * @param array the array to shallow clone, may be {@code null}
322 * @return the cloned array, {@code null} if {@code null} input
323 */
324 public static <T> T[] clone(final T[] array) {
325 if (array == null) {
326 return null;
327 }
328 return array.clone();
329 }
330
331 /**
332 * <p>Clones an array returning a typecast result and handling
333 * {@code null}.</p>
334 *
335 * <p>This method returns {@code null} for a {@code null} input array.</p>
336 *
337 * @param array the array to clone, may be {@code null}
338 * @return the cloned array, {@code null} if {@code null} input
339 */
340 public static long[] clone(final long[] array) {
341 if (array == null) {
342 return null;
343 }
344 return array.clone();
345 }
346
347 /**
348 * <p>Clones an array returning a typecast result and handling
349 * {@code null}.</p>
350 *
351 * <p>This method returns {@code null} for a {@code null} input array.</p>
352 *
353 * @param array the array to clone, may be {@code null}
354 * @return the cloned array, {@code null} if {@code null} input
355 */
356 public static int[] clone(final int[] array) {
357 if (array == null) {
358 return null;
359 }
360 return array.clone();
361 }
362
363 /**
364 * <p>Clones an array returning a typecast result and handling
365 * {@code null}.</p>
366 *
367 * <p>This method returns {@code null} for a {@code null} input array.</p>
368 *
369 * @param array the array to clone, may be {@code null}
370 * @return the cloned array, {@code null} if {@code null} input
371 */
372 public static short[] clone(final short[] array) {
373 if (array == null) {
374 return null;
375 }
376 return array.clone();
377 }
378
379 /**
380 * <p>Clones an array returning a typecast result and handling
381 * {@code null}.</p>
382 *
383 * <p>This method returns {@code null} for a {@code null} input array.</p>
384 *
385 * @param array the array to clone, may be {@code null}
386 * @return the cloned array, {@code null} if {@code null} input
387 */
388 public static char[] clone(final char[] array) {
389 if (array == null) {
390 return null;
391 }
392 return array.clone();
393 }
394
395 /**
396 * <p>Clones an array returning a typecast result and handling
397 * {@code null}.</p>
398 *
399 * <p>This method returns {@code null} for a {@code null} input array.</p>
400 *
401 * @param array the array to clone, may be {@code null}
402 * @return the cloned array, {@code null} if {@code null} input
403 */
404 public static byte[] clone(final byte[] array) {
405 if (array == null) {
406 return null;
407 }
408 return array.clone();
409 }
410
411 /**
412 * <p>Clones an array returning a typecast result and handling
413 * {@code null}.</p>
414 *
415 * <p>This method returns {@code null} for a {@code null} input array.</p>
416 *
417 * @param array the array to clone, may be {@code null}
418 * @return the cloned array, {@code null} if {@code null} input
419 */
420 public static double[] clone(final double[] array) {
421 if (array == null) {
422 return null;
423 }
424 return array.clone();
425 }
426
427 /**
428 * <p>Clones an array returning a typecast result and handling
429 * {@code null}.</p>
430 *
431 * <p>This method returns {@code null} for a {@code null} input array.</p>
432 *
433 * @param array the array to clone, may be {@code null}
434 * @return the cloned array, {@code null} if {@code null} input
435 */
436 public static float[] clone(final float[] array) {
437 if (array == null) {
438 return null;
439 }
440 return array.clone();
441 }
442
443 /**
444 * <p>Clones an array returning a typecast result and handling
445 * {@code null}.</p>
446 *
447 * <p>This method returns {@code null} for a {@code null} input array.</p>
448 *
449 * @param array the array to clone, may be {@code null}
450 * @return the cloned array, {@code null} if {@code null} input
451 */
452 public static boolean[] clone(final boolean[] array) {
453 if (array == null) {
454 return null;
455 }
456 return array.clone();
457 }
458
459 // nullToEmpty
460 //-----------------------------------------------------------------------
461 /**
462 * <p>Defensive programming technique to change a {@code null}
463 * reference to an empty one.</p>
464 *
465 * <p>This method returns an empty array for a {@code null} input array.</p>
466 *
467 * <p>As a memory optimizing technique an empty array passed in will be overridden with
468 * the empty {@code public static} references in this class.</p>
469 *
470 * @param array the array to check for {@code null} or empty
471 * @return the same array, {@code public static} empty array if {@code null} or empty input
472 * @since 2.5
473 */
474 public static Object[] nullToEmpty(final Object[] array) {
475 if (isEmpty(array)) {
476 return EMPTY_OBJECT_ARRAY;
477 }
478 return array;
479 }
480
481 /**
482 * <p>Defensive programming technique to change a {@code null}
483 * reference to an empty one.</p>
484 *
485 * <p>This method returns an empty array for a {@code null} input array.</p>
486 *
487 * <p>As a memory optimizing technique an empty array passed in will be overridden with
488 * the empty {@code public static} references in this class.</p>
489 *
490 * @param array the array to check for {@code null} or empty
491 * @return the same array, {@code public static} empty array if {@code null} or empty input
492 * @since 3.2
493 */
494 public static Class<?>[] nullToEmpty(final Class<?>[] array) {
495 if (isEmpty(array)) {
496 return EMPTY_CLASS_ARRAY;
497 }
498 return array;
499 }
500
501 /**
502 * <p>Defensive programming technique to change a {@code null}
503 * reference to an empty one.</p>
504 *
505 * <p>This method returns an empty array for a {@code null} input array.</p>
506 *
507 * <p>As a memory optimizing technique an empty array passed in will be overridden with
508 * the empty {@code public static} references in this class.</p>
509 *
510 * @param array the array to check for {@code null} or empty
511 * @return the same array, {@code public static} empty array if {@code null} or empty input
512 * @since 2.5
513 */
514 public static String[] nullToEmpty(final String[] array) {
515 if (isEmpty(array)) {
516 return EMPTY_STRING_ARRAY;
517 }
518 return array;
519 }
520
521 /**
522 * <p>Defensive programming technique to change a {@code null}
523 * reference to an empty one.</p>
524 *
525 * <p>This method returns an empty array for a {@code null} input array.</p>
526 *
527 * <p>As a memory optimizing technique an empty array passed in will be overridden with
528 * the empty {@code public static} references in this class.</p>
529 *
530 * @param array the array to check for {@code null} or empty
531 * @return the same array, {@code public static} empty array if {@code null} or empty input
532 * @since 2.5
533 */
534 public static long[] nullToEmpty(final long[] array) {
535 if (isEmpty(array)) {
536 return EMPTY_LONG_ARRAY;
537 }
538 return array;
539 }
540
541 /**
542 * <p>Defensive programming technique to change a {@code null}
543 * reference to an empty one.</p>
544 *
545 * <p>This method returns an empty array for a {@code null} input array.</p>
546 *
547 * <p>As a memory optimizing technique an empty array passed in will be overridden with
548 * the empty {@code public static} references in this class.</p>
549 *
550 * @param array the array to check for {@code null} or empty
551 * @return the same array, {@code public static} empty array if {@code null} or empty input
552 * @since 2.5
553 */
554 public static int[] nullToEmpty(final int[] array) {
555 if (isEmpty(array)) {
556 return EMPTY_INT_ARRAY;
557 }
558 return array;
559 }
560
561 /**
562 * <p>Defensive programming technique to change a {@code null}
563 * reference to an empty one.</p>
564 *
565 * <p>This method returns an empty array for a {@code null} input array.</p>
566 *
567 * <p>As a memory optimizing technique an empty array passed in will be overridden with
568 * the empty {@code public static} references in this class.</p>
569 *
570 * @param array the array to check for {@code null} or empty
571 * @return the same array, {@code public static} empty array if {@code null} or empty input
572 * @since 2.5
573 */
574 public static short[] nullToEmpty(final short[] array) {
575 if (isEmpty(array)) {
576 return EMPTY_SHORT_ARRAY;
577 }
578 return array;
579 }
580
581 /**
582 * <p>Defensive programming technique to change a {@code null}
583 * reference to an empty one.</p>
584 *
585 * <p>This method returns an empty array for a {@code null} input array.</p>
586 *
587 * <p>As a memory optimizing technique an empty array passed in will be overridden with
588 * the empty {@code public static} references in this class.</p>
589 *
590 * @param array the array to check for {@code null} or empty
591 * @return the same array, {@code public static} empty array if {@code null} or empty input
592 * @since 2.5
593 */
594 public static char[] nullToEmpty(final char[] array) {
595 if (isEmpty(array)) {
596 return EMPTY_CHAR_ARRAY;
597 }
598 return array;
599 }
600
601 /**
602 * <p>Defensive programming technique to change a {@code null}
603 * reference to an empty one.</p>
604 *
605 * <p>This method returns an empty array for a {@code null} input array.</p>
606 *
607 * <p>As a memory optimizing technique an empty array passed in will be overridden with
608 * the empty {@code public static} references in this class.</p>
609 *
610 * @param array the array to check for {@code null} or empty
611 * @return the same array, {@code public static} empty array if {@code null} or empty input
612 * @since 2.5
613 */
614 public static byte[] nullToEmpty(final byte[] array) {
615 if (isEmpty(array)) {
616 return EMPTY_BYTE_ARRAY;
617 }
618 return array;
619 }
620
621 /**
622 * <p>Defensive programming technique to change a {@code null}
623 * reference to an empty one.</p>
624 *
625 * <p>This method returns an empty array for a {@code null} input array.</p>
626 *
627 * <p>As a memory optimizing technique an empty array passed in will be overridden with
628 * the empty {@code public static} references in this class.</p>
629 *
630 * @param array the array to check for {@code null} or empty
631 * @return the same array, {@code public static} empty array if {@code null} or empty input
632 * @since 2.5
633 */
634 public static double[] nullToEmpty(final double[] array) {
635 if (isEmpty(array)) {
636 return EMPTY_DOUBLE_ARRAY;
637 }
638 return array;
639 }
640
641 /**
642 * <p>Defensive programming technique to change a {@code null}
643 * reference to an empty one.</p>
644 *
645 * <p>This method returns an empty array for a {@code null} input array.</p>
646 *
647 * <p>As a memory optimizing technique an empty array passed in will be overridden with
648 * the empty {@code public static} references in this class.</p>
649 *
650 * @param array the array to check for {@code null} or empty
651 * @return the same array, {@code public static} empty array if {@code null} or empty input
652 * @since 2.5
653 */
654 public static float[] nullToEmpty(final float[] array) {
655 if (isEmpty(array)) {
656 return EMPTY_FLOAT_ARRAY;
657 }
658 return array;
659 }
660
661 /**
662 * <p>Defensive programming technique to change a {@code null}
663 * reference to an empty one.</p>
664 *
665 * <p>This method returns an empty array for a {@code null} input array.</p>
666 *
667 * <p>As a memory optimizing technique an empty array passed in will be overridden with
668 * the empty {@code public static} references in this class.</p>
669 *
670 * @param array the array to check for {@code null} or empty
671 * @return the same array, {@code public static} empty array if {@code null} or empty input
672 * @since 2.5
673 */
674 public static boolean[] nullToEmpty(final boolean[] array) {
675 if (isEmpty(array)) {
676 return EMPTY_BOOLEAN_ARRAY;
677 }
678 return array;
679 }
680
681 /**
682 * <p>Defensive programming technique to change a {@code null}
683 * reference to an empty one.</p>
684 *
685 * <p>This method returns an empty array for a {@code null} input array.</p>
686 *
687 * <p>As a memory optimizing technique an empty array passed in will be overridden with
688 * the empty {@code public static} references in this class.</p>
689 *
690 * @param array the array to check for {@code null} or empty
691 * @return the same array, {@code public static} empty array if {@code null} or empty input
692 * @since 2.5
693 */
694 public static Long[] nullToEmpty(final Long[] array) {
695 if (isEmpty(array)) {
696 return EMPTY_LONG_OBJECT_ARRAY;
697 }
698 return array;
699 }
700
701 /**
702 * <p>Defensive programming technique to change a {@code null}
703 * reference to an empty one.</p>
704 *
705 * <p>This method returns an empty array for a {@code null} input array.</p>
706 *
707 * <p>As a memory optimizing technique an empty array passed in will be overridden with
708 * the empty {@code public static} references in this class.</p>
709 *
710 * @param array the array to check for {@code null} or empty
711 * @return the same array, {@code public static} empty array if {@code null} or empty input
712 * @since 2.5
713 */
714 public static Integer[] nullToEmpty(final Integer[] array) {
715 if (isEmpty(array)) {
716 return EMPTY_INTEGER_OBJECT_ARRAY;
717 }
718 return array;
719 }
720
721 /**
722 * <p>Defensive programming technique to change a {@code null}
723 * reference to an empty one.</p>
724 *
725 * <p>This method returns an empty array for a {@code null} input array.</p>
726 *
727 * <p>As a memory optimizing technique an empty array passed in will be overridden with
728 * the empty {@code public static} references in this class.</p>
729 *
730 * @param array the array to check for {@code null} or empty
731 * @return the same array, {@code public static} empty array if {@code null} or empty input
732 * @since 2.5
733 */
734 public static Short[] nullToEmpty(final Short[] array) {
735 if (isEmpty(array)) {
736 return EMPTY_SHORT_OBJECT_ARRAY;
737 }
738 return array;
739 }
740
741 /**
742 * <p>Defensive programming technique to change a {@code null}
743 * reference to an empty one.</p>
744 *
745 * <p>This method returns an empty array for a {@code null} input array.</p>
746 *
747 * <p>As a memory optimizing technique an empty array passed in will be overridden with
748 * the empty {@code public static} references in this class.</p>
749 *
750 * @param array the array to check for {@code null} or empty
751 * @return the same array, {@code public static} empty array if {@code null} or empty input
752 * @since 2.5
753 */
754 public static Character[] nullToEmpty(final Character[] array) {
755 if (isEmpty(array)) {
756 return EMPTY_CHARACTER_OBJECT_ARRAY;
757 }
758 return array;
759 }
760
761 /**
762 * <p>Defensive programming technique to change a {@code null}
763 * reference to an empty one.</p>
764 *
765 * <p>This method returns an empty array for a {@code null} input array.</p>
766 *
767 * <p>As a memory optimizing technique an empty array passed in will be overridden with
768 * the empty {@code public static} references in this class.</p>
769 *
770 * @param array the array to check for {@code null} or empty
771 * @return the same array, {@code public static} empty array if {@code null} or empty input
772 * @since 2.5
773 */
774 public static Byte[] nullToEmpty(final Byte[] array) {
775 if (isEmpty(array)) {
776 return EMPTY_BYTE_OBJECT_ARRAY;
777 }
778 return array;
779 }
780
781 /**
782 * <p>Defensive programming technique to change a {@code null}
783 * reference to an empty one.</p>
784 *
785 * <p>This method returns an empty array for a {@code null} input array.</p>
786 *
787 * <p>As a memory optimizing technique an empty array passed in will be overridden with
788 * the empty {@code public static} references in this class.</p>
789 *
790 * @param array the array to check for {@code null} or empty
791 * @return the same array, {@code public static} empty array if {@code null} or empty input
792 * @since 2.5
793 */
794 public static Double[] nullToEmpty(final Double[] array) {
795 if (isEmpty(array)) {
796 return EMPTY_DOUBLE_OBJECT_ARRAY;
797 }
798 return array;
799 }
800
801 /**
802 * <p>Defensive programming technique to change a {@code null}
803 * reference to an empty one.</p>
804 *
805 * <p>This method returns an empty array for a {@code null} input array.</p>
806 *
807 * <p>As a memory optimizing technique an empty array passed in will be overridden with
808 * the empty {@code public static} references in this class.</p>
809 *
810 * @param array the array to check for {@code null} or empty
811 * @return the same array, {@code public static} empty array if {@code null} or empty input
812 * @since 2.5
813 */
814 public static Float[] nullToEmpty(final Float[] array) {
815 if (isEmpty(array)) {
816 return EMPTY_FLOAT_OBJECT_ARRAY;
817 }
818 return array;
819 }
820
821 /**
822 * <p>Defensive programming technique to change a {@code null}
823 * reference to an empty one.</p>
824 *
825 * <p>This method returns an empty array for a {@code null} input array.</p>
826 *
827 * <p>As a memory optimizing technique an empty array passed in will be overridden with
828 * the empty {@code public static} references in this class.</p>
829 *
830 * @param array the array to check for {@code null} or empty
831 * @return the same array, {@code public static} empty array if {@code null} or empty input
832 * @since 2.5
833 */
834 public static Boolean[] nullToEmpty(final Boolean[] array) {
835 if (isEmpty(array)) {
836 return EMPTY_BOOLEAN_OBJECT_ARRAY;
837 }
838 return array;
839 }
840
841 // Subarrays
842 //-----------------------------------------------------------------------
843 /**
844 * <p>Produces a new array containing the elements between
845 * the start and end indices.</p>
846 *
847 * <p>The start index is inclusive, the end index exclusive.
848 * Null array input produces null output.</p>
849 *
850 * <p>The component type of the subarray is always the same as
851 * that of the input array. Thus, if the input is an array of type
852 * {@code Date}, the following usage is envisaged:</p>
853 *
854 * <pre>
855 * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
856 * </pre>
857 *
858 * @param <T> the component type of the array
859 * @param array the array
860 * @param startIndexInclusive the starting index. Undervalue (<0)
861 * is promoted to 0, overvalue (>array.length) results
862 * in an empty array.
863 * @param endIndexExclusive elements up to endIndex-1 are present in the
864 * returned subarray. Undervalue (< startIndex) produces
865 * empty array, overvalue (>array.length) is demoted to
866 * array length.
867 * @return a new array containing the elements between
868 * the start and end indices.
869 * @since 2.1
870 * @see Arrays#copyOfRange(Object[], int, int)
871 */
872 public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
873 if (array == null) {
874 return null;
875 }
876 if (startIndexInclusive < 0) {
877 startIndexInclusive = 0;
878 }
879 if (endIndexExclusive > array.length) {
880 endIndexExclusive = array.length;
881 }
882 final int newSize = endIndexExclusive - startIndexInclusive;
883 final Class<?> type = array.getClass().getComponentType();
884 if (newSize <= 0) {
885 @SuppressWarnings("unchecked") // OK, because array is of type T
886 final T[] emptyArray = (T[]) Array.newInstance(type, 0);
887 return emptyArray;
888 }
889 @SuppressWarnings("unchecked") // OK, because array is of type T
890 final
891 T[] subarray = (T[]) Array.newInstance(type, newSize);
892 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
893 return subarray;
894 }
895
896 /**
897 * <p>Produces a new {@code long} array containing the elements
898 * between the start and end indices.</p>
899 *
900 * <p>The start index is inclusive, the end index exclusive.
901 * Null array input produces null output.</p>
902 *
903 * @param array the array
904 * @param startIndexInclusive the starting index. Undervalue (<0)
905 * is promoted to 0, overvalue (>array.length) results
906 * in an empty array.
907 * @param endIndexExclusive elements up to endIndex-1 are present in the
908 * returned subarray. Undervalue (< startIndex) produces
909 * empty array, overvalue (>array.length) is demoted to
910 * array length.
911 * @return a new array containing the elements between
912 * the start and end indices.
913 * @since 2.1
914 * @see Arrays#copyOfRange(long[], int, int)
915 */
916 public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
917 if (array == null) {
918 return null;
919 }
920 if (startIndexInclusive < 0) {
921 startIndexInclusive = 0;
922 }
923 if (endIndexExclusive > array.length) {
924 endIndexExclusive = array.length;
925 }
926 final int newSize = endIndexExclusive - startIndexInclusive;
927 if (newSize <= 0) {
928 return EMPTY_LONG_ARRAY;
929 }
930
931 final long[] subarray = new long[newSize];
932 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
933 return subarray;
934 }
935
936 /**
937 * <p>Produces a new {@code int} array containing the elements
938 * between the start and end indices.</p>
939 *
940 * <p>The start index is inclusive, the end index exclusive.
941 * Null array input produces null output.</p>
942 *
943 * @param array the array
944 * @param startIndexInclusive the starting index. Undervalue (<0)
945 * is promoted to 0, overvalue (>array.length) results
946 * in an empty array.
947 * @param endIndexExclusive elements up to endIndex-1 are present in the
948 * returned subarray. Undervalue (< startIndex) produces
949 * empty array, overvalue (>array.length) is demoted to
950 * array length.
951 * @return a new array containing the elements between
952 * the start and end indices.
953 * @since 2.1
954 * @see Arrays#copyOfRange(int[], int, int)
955 */
956 public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
957 if (array == null) {
958 return null;
959 }
960 if (startIndexInclusive < 0) {
961 startIndexInclusive = 0;
962 }
963 if (endIndexExclusive > array.length) {
964 endIndexExclusive = array.length;
965 }
966 final int newSize = endIndexExclusive - startIndexInclusive;
967 if (newSize <= 0) {
968 return EMPTY_INT_ARRAY;
969 }
970
971 final int[] subarray = new int[newSize];
972 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
973 return subarray;
974 }
975
976 /**
977 * <p>Produces a new {@code short} array containing the elements
978 * between the start and end indices.</p>
979 *
980 * <p>The start index is inclusive, the end index exclusive.
981 * Null array input produces null output.</p>
982 *
983 * @param array the array
984 * @param startIndexInclusive the starting index. Undervalue (<0)
985 * is promoted to 0, overvalue (>array.length) results
986 * in an empty array.
987 * @param endIndexExclusive elements up to endIndex-1 are present in the
988 * returned subarray. Undervalue (< startIndex) produces
989 * empty array, overvalue (>array.length) is demoted to
990 * array length.
991 * @return a new array containing the elements between
992 * the start and end indices.
993 * @since 2.1
994 * @see Arrays#copyOfRange(short[], int, int)
995 */
996 public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
997 if (array == null) {
998 return null;
999 }
1000 if (startIndexInclusive < 0) {
1001 startIndexInclusive = 0;
1002 }
1003 if (endIndexExclusive > array.length) {
1004 endIndexExclusive = array.length;
1005 }
1006 final int newSize = endIndexExclusive - startIndexInclusive;
1007 if (newSize <= 0) {
1008 return EMPTY_SHORT_ARRAY;
1009 }
1010
1011 final short[] subarray = new short[newSize];
1012 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1013 return subarray;
1014 }
1015
1016 /**
1017 * <p>Produces a new {@code char} array containing the elements
1018 * between the start and end indices.</p>
1019 *
1020 * <p>The start index is inclusive, the end index exclusive.
1021 * Null array input produces null output.</p>
1022 *
1023 * @param array the array
1024 * @param startIndexInclusive the starting index. Undervalue (<0)
1025 * is promoted to 0, overvalue (>array.length) results
1026 * in an empty array.
1027 * @param endIndexExclusive elements up to endIndex-1 are present in the
1028 * returned subarray. Undervalue (< startIndex) produces
1029 * empty array, overvalue (>array.length) is demoted to
1030 * array length.
1031 * @return a new array containing the elements between
1032 * the start and end indices.
1033 * @since 2.1
1034 * @see Arrays#copyOfRange(char[], int, int)
1035 */
1036 public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
1037 if (array == null) {
1038 return null;
1039 }
1040 if (startIndexInclusive < 0) {
1041 startIndexInclusive = 0;
1042 }
1043 if (endIndexExclusive > array.length) {
1044 endIndexExclusive = array.length;
1045 }
1046 final int newSize = endIndexExclusive - startIndexInclusive;
1047 if (newSize <= 0) {
1048 return EMPTY_CHAR_ARRAY;
1049 }
1050
1051 final char[] subarray = new char[newSize];
1052 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1053 return subarray;
1054 }
1055
1056 /**
1057 * <p>Produces a new {@code byte} array containing the elements
1058 * between the start and end indices.</p>
1059 *
1060 * <p>The start index is inclusive, the end index exclusive.
1061 * Null array input produces null output.</p>
1062 *
1063 * @param array the array
1064 * @param startIndexInclusive the starting index. Undervalue (<0)
1065 * is promoted to 0, overvalue (>array.length) results
1066 * in an empty array.
1067 * @param endIndexExclusive elements up to endIndex-1 are present in the
1068 * returned subarray. Undervalue (< startIndex) produces
1069 * empty array, overvalue (>array.length) is demoted to
1070 * array length.
1071 * @return a new array containing the elements between
1072 * the start and end indices.
1073 * @since 2.1
1074 * @see Arrays#copyOfRange(byte[], int, int)
1075 */
1076 public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
1077 if (array == null) {
1078 return null;
1079 }
1080 if (startIndexInclusive < 0) {
1081 startIndexInclusive = 0;
1082 }
1083 if (endIndexExclusive > array.length) {
1084 endIndexExclusive = array.length;
1085 }
1086 final int newSize = endIndexExclusive - startIndexInclusive;
1087 if (newSize <= 0) {
1088 return EMPTY_BYTE_ARRAY;
1089 }
1090
1091 final byte[] subarray = new byte[newSize];
1092 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1093 return subarray;
1094 }
1095
1096 /**
1097 * <p>Produces a new {@code double} array containing the elements
1098 * between the start and end indices.</p>
1099 *
1100 * <p>The start index is inclusive, the end index exclusive.
1101 * Null array input produces null output.</p>
1102 *
1103 * @param array the array
1104 * @param startIndexInclusive the starting index. Undervalue (<0)
1105 * is promoted to 0, overvalue (>array.length) results
1106 * in an empty array.
1107 * @param endIndexExclusive elements up to endIndex-1 are present in the
1108 * returned subarray. Undervalue (< startIndex) produces
1109 * empty array, overvalue (>array.length) is demoted to
1110 * array length.
1111 * @return a new array containing the elements between
1112 * the start and end indices.
1113 * @since 2.1
1114 * @see Arrays#copyOfRange(double[], int, int)
1115 */
1116 public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
1117 if (array == null) {
1118 return null;
1119 }
1120 if (startIndexInclusive < 0) {
1121 startIndexInclusive = 0;
1122 }
1123 if (endIndexExclusive > array.length) {
1124 endIndexExclusive = array.length;
1125 }
1126 final int newSize = endIndexExclusive - startIndexInclusive;
1127 if (newSize <= 0) {
1128 return EMPTY_DOUBLE_ARRAY;
1129 }
1130
1131 final double[] subarray = new double[newSize];
1132 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1133 return subarray;
1134 }
1135
1136 /**
1137 * <p>Produces a new {@code float} array containing the elements
1138 * between the start and end indices.</p>
1139 *
1140 * <p>The start index is inclusive, the end index exclusive.
1141 * Null array input produces null output.</p>
1142 *
1143 * @param array the array
1144 * @param startIndexInclusive the starting index. Undervalue (<0)
1145 * is promoted to 0, overvalue (>array.length) results
1146 * in an empty array.
1147 * @param endIndexExclusive elements up to endIndex-1 are present in the
1148 * returned subarray. Undervalue (< startIndex) produces
1149 * empty array, overvalue (>array.length) is demoted to
1150 * array length.
1151 * @return a new array containing the elements between
1152 * the start and end indices.
1153 * @since 2.1
1154 * @see Arrays#copyOfRange(float[], int, int)
1155 */
1156 public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
1157 if (array == null) {
1158 return null;
1159 }
1160 if (startIndexInclusive < 0) {
1161 startIndexInclusive = 0;
1162 }
1163 if (endIndexExclusive > array.length) {
1164 endIndexExclusive = array.length;
1165 }
1166 final int newSize = endIndexExclusive - startIndexInclusive;
1167 if (newSize <= 0) {
1168 return EMPTY_FLOAT_ARRAY;
1169 }
1170
1171 final float[] subarray = new float[newSize];
1172 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1173 return subarray;
1174 }
1175
1176 /**
1177 * <p>Produces a new {@code boolean} array containing the elements
1178 * between the start and end indices.</p>
1179 *
1180 * <p>The start index is inclusive, the end index exclusive.
1181 * Null array input produces null output.</p>
1182 *
1183 * @param array the array
1184 * @param startIndexInclusive the starting index. Undervalue (<0)
1185 * is promoted to 0, overvalue (>array.length) results
1186 * in an empty array.
1187 * @param endIndexExclusive elements up to endIndex-1 are present in the
1188 * returned subarray. Undervalue (< startIndex) produces
1189 * empty array, overvalue (>array.length) is demoted to
1190 * array length.
1191 * @return a new array containing the elements between
1192 * the start and end indices.
1193 * @since 2.1
1194 * @see Arrays#copyOfRange(boolean[], int, int)
1195 */
1196 public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
1197 if (array == null) {
1198 return null;
1199 }
1200 if (startIndexInclusive < 0) {
1201 startIndexInclusive = 0;
1202 }
1203 if (endIndexExclusive > array.length) {
1204 endIndexExclusive = array.length;
1205 }
1206 final int newSize = endIndexExclusive - startIndexInclusive;
1207 if (newSize <= 0) {
1208 return EMPTY_BOOLEAN_ARRAY;
1209 }
1210
1211 final boolean[] subarray = new boolean[newSize];
1212 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1213 return subarray;
1214 }
1215
1216 // Is same length
1217 //-----------------------------------------------------------------------
1218 /**
1219 * <p>Checks whether two arrays are the same length, treating
1220 * {@code null} arrays as length {@code 0}.
1221 *
1222 * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
1223 *
1224 * @param array1 the first array, may be {@code null}
1225 * @param array2 the second array, may be {@code null}
1226 * @return {@code true} if length of arrays matches, treating
1227 * {@code null} as an empty array
1228 */
1229 public static boolean isSameLength(final Object[] array1, final Object[] array2) {
1230 if ((array1 == null && array2 != null && array2.length > 0) ||
1231 (array2 == null && array1 != null && array1.length > 0) ||
1232 (array1 != null && array2 != null && array1.length != array2.length)) {
1233 return false;
1234 }
1235 return true;
1236 }
1237
1238 /**
1239 * <p>Checks whether two arrays are the same length, treating
1240 * {@code null} arrays as length {@code 0}.</p>
1241 *
1242 * @param array1 the first array, may be {@code null}
1243 * @param array2 the second array, may be {@code null}
1244 * @return {@code true} if length of arrays matches, treating
1245 * {@code null} as an empty array
1246 */
1247 public static boolean isSameLength(final long[] array1, final long[] array2) {
1248 if ((array1 == null && array2 != null && array2.length > 0) ||
1249 (array2 == null && array1 != null && array1.length > 0) ||
1250 (array1 != null && array2 != null && array1.length != array2.length)) {
1251 return false;
1252 }
1253 return true;
1254 }
1255
1256 /**
1257 * <p>Checks whether two arrays are the same length, treating
1258 * {@code null} arrays as length {@code 0}.</p>
1259 *
1260 * @param array1 the first array, may be {@code null}
1261 * @param array2 the second array, may be {@code null}
1262 * @return {@code true} if length of arrays matches, treating
1263 * {@code null} as an empty array
1264 */
1265 public static boolean isSameLength(final int[] array1, final int[] array2) {
1266 if ((array1 == null && array2 != null && array2.length > 0) ||
1267 (array2 == null && array1 != null && array1.length > 0) ||
1268 (array1 != null && array2 != null && array1.length != array2.length)) {
1269 return false;
1270 }
1271 return true;
1272 }
1273
1274 /**
1275 * <p>Checks whether two arrays are the same length, treating
1276 * {@code null} arrays as length {@code 0}.</p>
1277 *
1278 * @param array1 the first array, may be {@code null}
1279 * @param array2 the second array, may be {@code null}
1280 * @return {@code true} if length of arrays matches, treating
1281 * {@code null} as an empty array
1282 */
1283 public static boolean isSameLength(final short[] array1, final short[] array2) {
1284 if ((array1 == null && array2 != null && array2.length > 0) ||
1285 (array2 == null && array1 != null && array1.length > 0) ||
1286 (array1 != null && array2 != null && array1.length != array2.length)) {
1287 return false;
1288 }
1289 return true;
1290 }
1291
1292 /**
1293 * <p>Checks whether two arrays are the same length, treating
1294 * {@code null} arrays as length {@code 0}.</p>
1295 *
1296 * @param array1 the first array, may be {@code null}
1297 * @param array2 the second array, may be {@code null}
1298 * @return {@code true} if length of arrays matches, treating
1299 * {@code null} as an empty array
1300 */
1301 public static boolean isSameLength(final char[] array1, final char[] array2) {
1302 if ((array1 == null && array2 != null && array2.length > 0) ||
1303 (array2 == null && array1 != null && array1.length > 0) ||
1304 (array1 != null && array2 != null && array1.length != array2.length)) {
1305 return false;
1306 }
1307 return true;
1308 }
1309
1310 /**
1311 * <p>Checks whether two arrays are the same length, treating
1312 * {@code null} arrays as length {@code 0}.</p>
1313 *
1314 * @param array1 the first array, may be {@code null}
1315 * @param array2 the second array, may be {@code null}
1316 * @return {@code true} if length of arrays matches, treating
1317 * {@code null} as an empty array
1318 */
1319 public static boolean isSameLength(final byte[] array1, final byte[] array2) {
1320 if ((array1 == null && array2 != null && array2.length > 0) ||
1321 (array2 == null && array1 != null && array1.length > 0) ||
1322 (array1 != null && array2 != null && array1.length != array2.length)) {
1323 return false;
1324 }
1325 return true;
1326 }
1327
1328 /**
1329 * <p>Checks whether two arrays are the same length, treating
1330 * {@code null} arrays as length {@code 0}.</p>
1331 *
1332 * @param array1 the first array, may be {@code null}
1333 * @param array2 the second array, may be {@code null}
1334 * @return {@code true} if length of arrays matches, treating
1335 * {@code null} as an empty array
1336 */
1337 public static boolean isSameLength(final double[] array1, final double[] array2) {
1338 if ((array1 == null && array2 != null && array2.length > 0) ||
1339 (array2 == null && array1 != null && array1.length > 0) ||
1340 (array1 != null && array2 != null && array1.length != array2.length)) {
1341 return false;
1342 }
1343 return true;
1344 }
1345
1346 /**
1347 * <p>Checks whether two arrays are the same length, treating
1348 * {@code null} arrays as length {@code 0}.</p>
1349 *
1350 * @param array1 the first array, may be {@code null}
1351 * @param array2 the second array, may be {@code null}
1352 * @return {@code true} if length of arrays matches, treating
1353 * {@code null} as an empty array
1354 */
1355 public static boolean isSameLength(final float[] array1, final float[] array2) {
1356 if ((array1 == null && array2 != null && array2.length > 0) ||
1357 (array2 == null && array1 != null && array1.length > 0) ||
1358 (array1 != null && array2 != null && array1.length != array2.length)) {
1359 return false;
1360 }
1361 return true;
1362 }
1363
1364 /**
1365 * <p>Checks whether two arrays are the same length, treating
1366 * {@code null} arrays as length {@code 0}.</p>
1367 *
1368 * @param array1 the first array, may be {@code null}
1369 * @param array2 the second array, may be {@code null}
1370 * @return {@code true} if length of arrays matches, treating
1371 * {@code null} as an empty array
1372 */
1373 public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
1374 if ((array1 == null && array2 != null && array2.length > 0) ||
1375 (array2 == null && array1 != null && array1.length > 0) ||
1376 (array1 != null && array2 != null && array1.length != array2.length)) {
1377 return false;
1378 }
1379 return true;
1380 }
1381
1382 //-----------------------------------------------------------------------
1383 /**
1384 * <p>Returns the length of the specified array.
1385 * This method can deal with {@code Object} arrays and with primitive arrays.</p>
1386 *
1387 * <p>If the input array is {@code null}, {@code 0} is returned.</p>
1388 *
1389 * <pre>
1390 * ArrayUtils.getLength(null) = 0
1391 * ArrayUtils.getLength([]) = 0
1392 * ArrayUtils.getLength([null]) = 1
1393 * ArrayUtils.getLength([true, false]) = 2
1394 * ArrayUtils.getLength([1, 2, 3]) = 3
1395 * ArrayUtils.getLength(["a", "b", "c"]) = 3
1396 * </pre>
1397 *
1398 * @param array the array to retrieve the length from, may be null
1399 * @return The length of the array, or {@code 0} if the array is {@code null}
1400 * @throws IllegalArgumentException if the object argument is not an array.
1401 * @since 2.1
1402 */
1403 public static int getLength(final Object array) {
1404 if (array == null) {
1405 return 0;
1406 }
1407 return Array.getLength(array);
1408 }
1409
1410 /**
1411 * <p>Checks whether two arrays are the same type taking into account
1412 * multi-dimensional arrays.</p>
1413 *
1414 * @param array1 the first array, must not be {@code null}
1415 * @param array2 the second array, must not be {@code null}
1416 * @return {@code true} if type of arrays matches
1417 * @throws IllegalArgumentException if either array is {@code null}
1418 */
1419 public static boolean isSameType(final Object array1, final Object array2) {
1420 if (array1 == null || array2 == null) {
1421 throw new IllegalArgumentException("The Array must not be null");
1422 }
1423 return array1.getClass().getName().equals(array2.getClass().getName());
1424 }
1425
1426 // Reverse
1427 //-----------------------------------------------------------------------
1428 /**
1429 * <p>Reverses the order of the given array.</p>
1430 *
1431 * <p>There is no special handling for multi-dimensional arrays.</p>
1432 *
1433 * <p>This method does nothing for a {@code null} input array.</p>
1434 *
1435 * @param array the array to reverse, may be {@code null}
1436 */
1437 public static void reverse(final Object[] array) {
1438 if (array == null) {
1439 return;
1440 }
1441 reverse(array, 0, array.length);
1442 }
1443
1444 /**
1445 * <p>Reverses the order of the given array.</p>
1446 *
1447 * <p>This method does nothing for a {@code null} input array.</p>
1448 *
1449 * @param array the array to reverse, may be {@code null}
1450 */
1451 public static void reverse(final long[] array) {
1452 if (array == null) {
1453 return;
1454 }
1455 reverse(array, 0, array.length);
1456 }
1457
1458 /**
1459 * <p>Reverses the order of the given array.</p>
1460 *
1461 * <p>This method does nothing for a {@code null} input array.</p>
1462 *
1463 * @param array the array to reverse, may be {@code null}
1464 */
1465 public static void reverse(final int[] array) {
1466 if (array == null) {
1467 return;
1468 }
1469 reverse(array, 0, array.length);
1470 }
1471
1472 /**
1473 * <p>Reverses the order of the given array.</p>
1474 *
1475 * <p>This method does nothing for a {@code null} input array.</p>
1476 *
1477 * @param array the array to reverse, may be {@code null}
1478 */
1479 public static void reverse(final short[] array) {
1480 if (array == null) {
1481 return;
1482 }
1483 reverse(array, 0, array.length);
1484 }
1485
1486 /**
1487 * <p>Reverses the order of the given array.</p>
1488 *
1489 * <p>This method does nothing for a {@code null} input array.</p>
1490 *
1491 * @param array the array to reverse, may be {@code null}
1492 */
1493 public static void reverse(final char[] array) {
1494 if (array == null) {
1495 return;
1496 }
1497 reverse(array, 0, array.length);
1498 }
1499
1500 /**
1501 * <p>Reverses the order of the given array.</p>
1502 *
1503 * <p>This method does nothing for a {@code null} input array.</p>
1504 *
1505 * @param array the array to reverse, may be {@code null}
1506 */
1507 public static void reverse(final byte[] array) {
1508 if (array == null) {
1509 return;
1510 }
1511 reverse(array, 0, array.length);
1512 }
1513
1514 /**
1515 * <p>Reverses the order of the given array.</p>
1516 *
1517 * <p>This method does nothing for a {@code null} input array.</p>
1518 *
1519 * @param array the array to reverse, may be {@code null}
1520 */
1521 public static void reverse(final double[] array) {
1522 if (array == null) {
1523 return;
1524 }
1525 reverse(array, 0, array.length);
1526 }
1527
1528 /**
1529 * <p>Reverses the order of the given array.</p>
1530 *
1531 * <p>This method does nothing for a {@code null} input array.</p>
1532 *
1533 * @param array the array to reverse, may be {@code null}
1534 */
1535 public static void reverse(final float[] array) {
1536 if (array == null) {
1537 return;
1538 }
1539 reverse(array, 0, array.length);
1540 }
1541
1542 /**
1543 * <p>Reverses the order of the given array.</p>
1544 *
1545 * <p>This method does nothing for a {@code null} input array.</p>
1546 *
1547 * @param array the array to reverse, may be {@code null}
1548 */
1549 public static void reverse(final boolean[] array) {
1550 if (array == null) {
1551 return;
1552 }
1553 reverse(array, 0, array.length);
1554 }
1555
1556 /**
1557 * <p>
1558 * Reverses the order of the given array in the given range.
1559 * </p>
1560 *
1561 * <p>
1562 * This method does nothing for a {@code null} input array.
1563 * </p>
1564 *
1565 * @param array
1566 * the array to reverse, may be {@code null}
1567 * @param startIndexInclusive
1568 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1569 * change.
1570 * @param endIndexExclusive
1571 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1572 * change. Overvalue (>array.length) is demoted to array length.
1573 * @since 3.2
1574 */
1575 public static void reverse(final boolean[] array, final int startIndexInclusive, final int endIndexExclusive) {
1576 if (array == null) {
1577 return;
1578 }
1579 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1580 int j = Math.min(array.length, endIndexExclusive) - 1;
1581 boolean tmp;
1582 while (j > i) {
1583 tmp = array[j];
1584 array[j] = array[i];
1585 array[i] = tmp;
1586 j--;
1587 i++;
1588 }
1589 }
1590
1591 /**
1592 * <p>
1593 * Reverses the order of the given array in the given range.
1594 * </p>
1595 *
1596 * <p>
1597 * This method does nothing for a {@code null} input array.
1598 * </p>
1599 *
1600 * @param array
1601 * the array to reverse, may be {@code null}
1602 * @param startIndexInclusive
1603 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1604 * change.
1605 * @param endIndexExclusive
1606 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1607 * change. Overvalue (>array.length) is demoted to array length.
1608 * @since 3.2
1609 */
1610 public static void reverse(final byte[] array, final int startIndexInclusive, final int endIndexExclusive) {
1611 if (array == null) {
1612 return;
1613 }
1614 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1615 int j = Math.min(array.length, endIndexExclusive) - 1;
1616 byte tmp;
1617 while (j > i) {
1618 tmp = array[j];
1619 array[j] = array[i];
1620 array[i] = tmp;
1621 j--;
1622 i++;
1623 }
1624 }
1625
1626 /**
1627 * <p>
1628 * Reverses the order of the given array in the given range.
1629 * </p>
1630 *
1631 * <p>
1632 * This method does nothing for a {@code null} input array.
1633 * </p>
1634 *
1635 * @param array
1636 * the array to reverse, may be {@code null}
1637 * @param startIndexInclusive
1638 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1639 * change.
1640 * @param endIndexExclusive
1641 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1642 * change. Overvalue (>array.length) is demoted to array length.
1643 * @since 3.2
1644 */
1645 public static void reverse(final char[] array, final int startIndexInclusive, final int endIndexExclusive) {
1646 if (array == null) {
1647 return;
1648 }
1649 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1650 int j = Math.min(array.length, endIndexExclusive) - 1;
1651 char tmp;
1652 while (j > i) {
1653 tmp = array[j];
1654 array[j] = array[i];
1655 array[i] = tmp;
1656 j--;
1657 i++;
1658 }
1659 }
1660
1661 /**
1662 * <p>
1663 * Reverses the order of the given array in the given range.
1664 * </p>
1665 *
1666 * <p>
1667 * This method does nothing for a {@code null} input array.
1668 * </p>
1669 *
1670 * @param array
1671 * the array to reverse, may be {@code null}
1672 * @param startIndexInclusive
1673 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1674 * change.
1675 * @param endIndexExclusive
1676 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1677 * change. Overvalue (>array.length) is demoted to array length.
1678 * @since 3.2
1679 */
1680 public static void reverse(final double[] array, final int startIndexInclusive, final int endIndexExclusive) {
1681 if (array == null) {
1682 return;
1683 }
1684 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1685 int j = Math.min(array.length, endIndexExclusive) - 1;
1686 double tmp;
1687 while (j > i) {
1688 tmp = array[j];
1689 array[j] = array[i];
1690 array[i] = tmp;
1691 j--;
1692 i++;
1693 }
1694 }
1695
1696 /**
1697 * <p>
1698 * Reverses the order of the given array in the given range.
1699 * </p>
1700 *
1701 * <p>
1702 * This method does nothing for a {@code null} input array.
1703 * </p>
1704 *
1705 * @param array
1706 * the array to reverse, may be {@code null}
1707 * @param startIndexInclusive
1708 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1709 * change.
1710 * @param endIndexExclusive
1711 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1712 * change. Overvalue (>array.length) is demoted to array length.
1713 * @since 3.2
1714 */
1715 public static void reverse(final float[] array, final int startIndexInclusive, final int endIndexExclusive) {
1716 if (array == null) {
1717 return;
1718 }
1719 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1720 int j = Math.min(array.length, endIndexExclusive) - 1;
1721 float tmp;
1722 while (j > i) {
1723 tmp = array[j];
1724 array[j] = array[i];
1725 array[i] = tmp;
1726 j--;
1727 i++;
1728 }
1729 }
1730
1731 /**
1732 * <p>
1733 * Reverses the order of the given array in the given range.
1734 * </p>
1735 *
1736 * <p>
1737 * This method does nothing for a {@code null} input array.
1738 * </p>
1739 *
1740 * @param array
1741 * the array to reverse, may be {@code null}
1742 * @param startIndexInclusive
1743 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1744 * change.
1745 * @param endIndexExclusive
1746 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1747 * change. Overvalue (>array.length) is demoted to array length.
1748 * @since 3.2
1749 */
1750 public static void reverse(final int[] array, final int startIndexInclusive, final int endIndexExclusive) {
1751 if (array == null) {
1752 return;
1753 }
1754 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1755 int j = Math.min(array.length, endIndexExclusive) - 1;
1756 int tmp;
1757 while (j > i) {
1758 tmp = array[j];
1759 array[j] = array[i];
1760 array[i] = tmp;
1761 j--;
1762 i++;
1763 }
1764 }
1765
1766 /**
1767 * <p>
1768 * Reverses the order of the given array in the given range.
1769 * </p>
1770 *
1771 * <p>
1772 * This method does nothing for a {@code null} input array.
1773 * </p>
1774 *
1775 * @param array
1776 * the array to reverse, may be {@code null}
1777 * @param startIndexInclusive
1778 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1779 * change.
1780 * @param endIndexExclusive
1781 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1782 * change. Overvalue (>array.length) is demoted to array length.
1783 * @since 3.2
1784 */
1785 public static void reverse(final long[] array, final int startIndexInclusive, final int endIndexExclusive) {
1786 if (array == null) {
1787 return;
1788 }
1789 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1790 int j = Math.min(array.length, endIndexExclusive) - 1;
1791 long tmp;
1792 while (j > i) {
1793 tmp = array[j];
1794 array[j] = array[i];
1795 array[i] = tmp;
1796 j--;
1797 i++;
1798 }
1799 }
1800
1801 /**
1802 * <p>
1803 * Reverses the order of the given array in the given range.
1804 * </p>
1805 *
1806 * <p>
1807 * This method does nothing for a {@code null} input array.
1808 * </p>
1809 *
1810 * @param array
1811 * the array to reverse, may be {@code null}
1812 * @param startIndexInclusive
1813 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1814 * change.
1815 * @param endIndexExclusive
1816 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1817 * change. Overvalue (>array.length) is demoted to array length.
1818 * @since 3.2
1819 */
1820 public static void reverse(final Object[] array, final int startIndexInclusive, final int endIndexExclusive) {
1821 if (array == null) {
1822 return;
1823 }
1824 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1825 int j = Math.min(array.length, endIndexExclusive) - 1;
1826 Object tmp;
1827 while (j > i) {
1828 tmp = array[j];
1829 array[j] = array[i];
1830 array[i] = tmp;
1831 j--;
1832 i++;
1833 }
1834 }
1835
1836 /**
1837 * <p>
1838 * Reverses the order of the given array in the given range.
1839 * </p>
1840 *
1841 * <p>
1842 * This method does nothing for a {@code null} input array.
1843 * </p>
1844 *
1845 * @param array
1846 * the array to reverse, may be {@code null}
1847 * @param startIndexInclusive
1848 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
1849 * change.
1850 * @param endIndexExclusive
1851 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
1852 * change. Overvalue (>array.length) is demoted to array length.
1853 * @since 3.2
1854 */
1855 public static void reverse(final short[] array, final int startIndexInclusive, final int endIndexExclusive) {
1856 if (array == null) {
1857 return;
1858 }
1859 int i = startIndexInclusive < 0 ? 0 : startIndexInclusive;
1860 int j = Math.min(array.length, endIndexExclusive) - 1;
1861 short tmp;
1862 while (j > i) {
1863 tmp = array[j];
1864 array[j] = array[i];
1865 array[i] = tmp;
1866 j--;
1867 i++;
1868 }
1869 }
1870
1871 // IndexOf search
1872 // ----------------------------------------------------------------------
1873
1874 // Object IndexOf
1875 //-----------------------------------------------------------------------
1876 /**
1877 * <p>Finds the index of the given object in the array.</p>
1878 *
1879 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1880 *
1881 * @param array the array to search through for the object, may be {@code null}
1882 * @param objectToFind the object to find, may be {@code null}
1883 * @return the index of the object within the array,
1884 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1885 */
1886 public static int indexOf(final Object[] array, final Object objectToFind) {
1887 return indexOf(array, objectToFind, 0);
1888 }
1889
1890 /**
1891 * <p>Finds the index of the given object in the array starting at the given index.</p>
1892 *
1893 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1894 *
1895 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1896 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
1897 *
1898 * @param array the array to search through for the object, may be {@code null}
1899 * @param objectToFind the object to find, may be {@code null}
1900 * @param startIndex the index to start searching at
1901 * @return the index of the object within the array starting at the index,
1902 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1903 */
1904 public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
1905 if (array == null) {
1906 return INDEX_NOT_FOUND;
1907 }
1908 if (startIndex < 0) {
1909 startIndex = 0;
1910 }
1911 if (objectToFind == null) {
1912 for (int i = startIndex; i < array.length; i++) {
1913 if (array[i] == null) {
1914 return i;
1915 }
1916 }
1917 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1918 for (int i = startIndex; i < array.length; i++) {
1919 if (objectToFind.equals(array[i])) {
1920 return i;
1921 }
1922 }
1923 }
1924 return INDEX_NOT_FOUND;
1925 }
1926
1927 /**
1928 * <p>Finds the last index of the given object within the array.</p>
1929 *
1930 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1931 *
1932 * @param array the array to travers backwords looking for the object, may be {@code null}
1933 * @param objectToFind the object to find, may be {@code null}
1934 * @return the last index of the object within the array,
1935 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1936 */
1937 public static int lastIndexOf(final Object[] array, final Object objectToFind) {
1938 return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
1939 }
1940
1941 /**
1942 * <p>Finds the last index of the given object in the array starting at the given index.</p>
1943 *
1944 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1945 *
1946 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
1947 * the array length will search from the end of the array.</p>
1948 *
1949 * @param array the array to traverse for looking for the object, may be {@code null}
1950 * @param objectToFind the object to find, may be {@code null}
1951 * @param startIndex the start index to travers backwards from
1952 * @return the last index of the object within the array,
1953 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1954 */
1955 public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
1956 if (array == null) {
1957 return INDEX_NOT_FOUND;
1958 }
1959 if (startIndex < 0) {
1960 return INDEX_NOT_FOUND;
1961 } else if (startIndex >= array.length) {
1962 startIndex = array.length - 1;
1963 }
1964 if (objectToFind == null) {
1965 for (int i = startIndex; i >= 0; i--) {
1966 if (array[i] == null) {
1967 return i;
1968 }
1969 }
1970 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1971 for (int i = startIndex; i >= 0; i--) {
1972 if (objectToFind.equals(array[i])) {
1973 return i;
1974 }
1975 }
1976 }
1977 return INDEX_NOT_FOUND;
1978 }
1979
1980 /**
1981 * <p>Checks if the object is in the given array.</p>
1982 *
1983 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
1984 *
1985 * @param array the array to search through
1986 * @param objectToFind the object to find
1987 * @return {@code true} if the array contains the object
1988 */
1989 public static boolean contains(final Object[] array, final Object objectToFind) {
1990 return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
1991 }
1992
1993 // long IndexOf
1994 //-----------------------------------------------------------------------
1995 /**
1996 * <p>Finds the index of the given value in the array.</p>
1997 *
1998 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1999 *
2000 * @param array the array to search through for the object, may be {@code null}
2001 * @param valueToFind the value to find
2002 * @return the index of the value within the array,
2003 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2004 */
2005 public static int indexOf(final long[] array, final long valueToFind) {
2006 return indexOf(array, valueToFind, 0);
2007 }
2008
2009 /**
2010 * <p>Finds the index of the given value in the array starting at the given index.</p>
2011 *
2012 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2013 *
2014 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2015 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2016 *
2017 * @param array the array to search through for the object, may be {@code null}
2018 * @param valueToFind the value to find
2019 * @param startIndex the index to start searching at
2020 * @return the index of the value within the array,
2021 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2022 */
2023 public static int indexOf(final long[] array, final long valueToFind, int startIndex) {
2024 if (array == null) {
2025 return INDEX_NOT_FOUND;
2026 }
2027 if (startIndex < 0) {
2028 startIndex = 0;
2029 }
2030 for (int i = startIndex; i < array.length; i++) {
2031 if (valueToFind == array[i]) {
2032 return i;
2033 }
2034 }
2035 return INDEX_NOT_FOUND;
2036 }
2037
2038 /**
2039 * <p>Finds the last index of the given value within the array.</p>
2040 *
2041 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2042 *
2043 * @param array the array to travers backwords looking for the object, may be {@code null}
2044 * @param valueToFind the object to find
2045 * @return the last index of the value within the array,
2046 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2047 */
2048 public static int lastIndexOf(final long[] array, final long valueToFind) {
2049 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2050 }
2051
2052 /**
2053 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2054 *
2055 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2056 *
2057 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2058 * array length will search from the end of the array.</p>
2059 *
2060 * @param array the array to traverse for looking for the object, may be {@code null}
2061 * @param valueToFind the value to find
2062 * @param startIndex the start index to travers backwards from
2063 * @return the last index of the value within the array,
2064 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2065 */
2066 public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
2067 if (array == null) {
2068 return INDEX_NOT_FOUND;
2069 }
2070 if (startIndex < 0) {
2071 return INDEX_NOT_FOUND;
2072 } else if (startIndex >= array.length) {
2073 startIndex = array.length - 1;
2074 }
2075 for (int i = startIndex; i >= 0; i--) {
2076 if (valueToFind == array[i]) {
2077 return i;
2078 }
2079 }
2080 return INDEX_NOT_FOUND;
2081 }
2082
2083 /**
2084 * <p>Checks if the value is in the given array.</p>
2085 *
2086 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2087 *
2088 * @param array the array to search through
2089 * @param valueToFind the value to find
2090 * @return {@code true} if the array contains the object
2091 */
2092 public static boolean contains(final long[] array, final long valueToFind) {
2093 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2094 }
2095
2096 // int IndexOf
2097 //-----------------------------------------------------------------------
2098 /**
2099 * <p>Finds the index of the given value in the array.</p>
2100 *
2101 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2102 *
2103 * @param array the array to search through for the object, may be {@code null}
2104 * @param valueToFind the value to find
2105 * @return the index of the value within the array,
2106 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2107 */
2108 public static int indexOf(final int[] array, final int valueToFind) {
2109 return indexOf(array, valueToFind, 0);
2110 }
2111
2112 /**
2113 * <p>Finds the index of the given value in the array starting at the given index.</p>
2114 *
2115 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2116 *
2117 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2118 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2119 *
2120 * @param array the array to search through for the object, may be {@code null}
2121 * @param valueToFind the value to find
2122 * @param startIndex the index to start searching at
2123 * @return the index of the value within the array,
2124 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2125 */
2126 public static int indexOf(final int[] array, final int valueToFind, int startIndex) {
2127 if (array == null) {
2128 return INDEX_NOT_FOUND;
2129 }
2130 if (startIndex < 0) {
2131 startIndex = 0;
2132 }
2133 for (int i = startIndex; i < array.length; i++) {
2134 if (valueToFind == array[i]) {
2135 return i;
2136 }
2137 }
2138 return INDEX_NOT_FOUND;
2139 }
2140
2141 /**
2142 * <p>Finds the last index of the given value within the array.</p>
2143 *
2144 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2145 *
2146 * @param array the array to travers backwords looking for the object, may be {@code null}
2147 * @param valueToFind the object to find
2148 * @return the last index of the value within the array,
2149 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2150 */
2151 public static int lastIndexOf(final int[] array, final int valueToFind) {
2152 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2153 }
2154
2155 /**
2156 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2157 *
2158 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2159 *
2160 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2161 * array length will search from the end of the array.</p>
2162 *
2163 * @param array the array to traverse for looking for the object, may be {@code null}
2164 * @param valueToFind the value to find
2165 * @param startIndex the start index to travers backwards from
2166 * @return the last index of the value within the array,
2167 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2168 */
2169 public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
2170 if (array == null) {
2171 return INDEX_NOT_FOUND;
2172 }
2173 if (startIndex < 0) {
2174 return INDEX_NOT_FOUND;
2175 } else if (startIndex >= array.length) {
2176 startIndex = array.length - 1;
2177 }
2178 for (int i = startIndex; i >= 0; i--) {
2179 if (valueToFind == array[i]) {
2180 return i;
2181 }
2182 }
2183 return INDEX_NOT_FOUND;
2184 }
2185
2186 /**
2187 * <p>Checks if the value is in the given array.</p>
2188 *
2189 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2190 *
2191 * @param array the array to search through
2192 * @param valueToFind the value to find
2193 * @return {@code true} if the array contains the object
2194 */
2195 public static boolean contains(final int[] array, final int valueToFind) {
2196 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2197 }
2198
2199 // short IndexOf
2200 //-----------------------------------------------------------------------
2201 /**
2202 * <p>Finds the index of the given value in the array.</p>
2203 *
2204 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2205 *
2206 * @param array the array to search through for the object, may be {@code null}
2207 * @param valueToFind the value to find
2208 * @return the index of the value within the array,
2209 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2210 */
2211 public static int indexOf(final short[] array, final short valueToFind) {
2212 return indexOf(array, valueToFind, 0);
2213 }
2214
2215 /**
2216 * <p>Finds the index of the given value in the array starting at the given index.</p>
2217 *
2218 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2219 *
2220 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2221 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2222 *
2223 * @param array the array to search through for the object, may be {@code null}
2224 * @param valueToFind the value to find
2225 * @param startIndex the index to start searching at
2226 * @return the index of the value within the array,
2227 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2228 */
2229 public static int indexOf(final short[] array, final short valueToFind, int startIndex) {
2230 if (array == null) {
2231 return INDEX_NOT_FOUND;
2232 }
2233 if (startIndex < 0) {
2234 startIndex = 0;
2235 }
2236 for (int i = startIndex; i < array.length; i++) {
2237 if (valueToFind == array[i]) {
2238 return i;
2239 }
2240 }
2241 return INDEX_NOT_FOUND;
2242 }
2243
2244 /**
2245 * <p>Finds the last index of the given value within the array.</p>
2246 *
2247 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2248 *
2249 * @param array the array to travers backwords looking for the object, may be {@code null}
2250 * @param valueToFind the object to find
2251 * @return the last index of the value within the array,
2252 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2253 */
2254 public static int lastIndexOf(final short[] array, final short valueToFind) {
2255 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2256 }
2257
2258 /**
2259 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2260 *
2261 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2262 *
2263 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2264 * array length will search from the end of the array.</p>
2265 *
2266 * @param array the array to traverse for looking for the object, may be {@code null}
2267 * @param valueToFind the value to find
2268 * @param startIndex the start index to travers backwards from
2269 * @return the last index of the value within the array,
2270 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2271 */
2272 public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
2273 if (array == null) {
2274 return INDEX_NOT_FOUND;
2275 }
2276 if (startIndex < 0) {
2277 return INDEX_NOT_FOUND;
2278 } else if (startIndex >= array.length) {
2279 startIndex = array.length - 1;
2280 }
2281 for (int i = startIndex; i >= 0; i--) {
2282 if (valueToFind == array[i]) {
2283 return i;
2284 }
2285 }
2286 return INDEX_NOT_FOUND;
2287 }
2288
2289 /**
2290 * <p>Checks if the value is in the given array.</p>
2291 *
2292 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2293 *
2294 * @param array the array to search through
2295 * @param valueToFind the value to find
2296 * @return {@code true} if the array contains the object
2297 */
2298 public static boolean contains(final short[] array, final short valueToFind) {
2299 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2300 }
2301
2302 // char IndexOf
2303 //-----------------------------------------------------------------------
2304 /**
2305 * <p>Finds the index of the given value in the array.</p>
2306 *
2307 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2308 *
2309 * @param array the array to search through for the object, may be {@code null}
2310 * @param valueToFind the value to find
2311 * @return the index of the value within the array,
2312 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2313 * @since 2.1
2314 */
2315 public static int indexOf(final char[] array, final char valueToFind) {
2316 return indexOf(array, valueToFind, 0);
2317 }
2318
2319 /**
2320 * <p>Finds the index of the given value in the array starting at the given index.</p>
2321 *
2322 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2323 *
2324 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2325 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2326 *
2327 * @param array the array to search through for the object, may be {@code null}
2328 * @param valueToFind the value to find
2329 * @param startIndex the index to start searching at
2330 * @return the index of the value within the array,
2331 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2332 * @since 2.1
2333 */
2334 public static int indexOf(final char[] array, final char valueToFind, int startIndex) {
2335 if (array == null) {
2336 return INDEX_NOT_FOUND;
2337 }
2338 if (startIndex < 0) {
2339 startIndex = 0;
2340 }
2341 for (int i = startIndex; i < array.length; i++) {
2342 if (valueToFind == array[i]) {
2343 return i;
2344 }
2345 }
2346 return INDEX_NOT_FOUND;
2347 }
2348
2349 /**
2350 * <p>Finds the last index of the given value within the array.</p>
2351 *
2352 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2353 *
2354 * @param array the array to travers backwords looking for the object, may be {@code null}
2355 * @param valueToFind the object to find
2356 * @return the last index of the value within the array,
2357 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2358 * @since 2.1
2359 */
2360 public static int lastIndexOf(final char[] array, final char valueToFind) {
2361 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2362 }
2363
2364 /**
2365 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2366 *
2367 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2368 *
2369 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2370 * array length will search from the end of the array.</p>
2371 *
2372 * @param array the array to traverse for looking for the object, may be {@code null}
2373 * @param valueToFind the value to find
2374 * @param startIndex the start index to travers backwards from
2375 * @return the last index of the value within the array,
2376 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2377 * @since 2.1
2378 */
2379 public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
2380 if (array == null) {
2381 return INDEX_NOT_FOUND;
2382 }
2383 if (startIndex < 0) {
2384 return INDEX_NOT_FOUND;
2385 } else if (startIndex >= array.length) {
2386 startIndex = array.length - 1;
2387 }
2388 for (int i = startIndex; i >= 0; i--) {
2389 if (valueToFind == array[i]) {
2390 return i;
2391 }
2392 }
2393 return INDEX_NOT_FOUND;
2394 }
2395
2396 /**
2397 * <p>Checks if the value is in the given array.</p>
2398 *
2399 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2400 *
2401 * @param array the array to search through
2402 * @param valueToFind the value to find
2403 * @return {@code true} if the array contains the object
2404 * @since 2.1
2405 */
2406 public static boolean contains(final char[] array, final char valueToFind) {
2407 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2408 }
2409
2410 // byte IndexOf
2411 //-----------------------------------------------------------------------
2412 /**
2413 * <p>Finds the index of the given value in the array.</p>
2414 *
2415 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2416 *
2417 * @param array the array to search through for the object, may be {@code null}
2418 * @param valueToFind the value to find
2419 * @return the index of the value within the array,
2420 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2421 */
2422 public static int indexOf(final byte[] array, final byte valueToFind) {
2423 return indexOf(array, valueToFind, 0);
2424 }
2425
2426 /**
2427 * <p>Finds the index of the given value in the array starting at the given index.</p>
2428 *
2429 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2430 *
2431 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2432 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2433 *
2434 * @param array the array to search through for the object, may be {@code null}
2435 * @param valueToFind the value to find
2436 * @param startIndex the index to start searching at
2437 * @return the index of the value within the array,
2438 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2439 */
2440 public static int indexOf(final byte[] array, final byte valueToFind, int startIndex) {
2441 if (array == null) {
2442 return INDEX_NOT_FOUND;
2443 }
2444 if (startIndex < 0) {
2445 startIndex = 0;
2446 }
2447 for (int i = startIndex; i < array.length; i++) {
2448 if (valueToFind == array[i]) {
2449 return i;
2450 }
2451 }
2452 return INDEX_NOT_FOUND;
2453 }
2454
2455 /**
2456 * <p>Finds the last index of the given value within the array.</p>
2457 *
2458 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2459 *
2460 * @param array the array to travers backwords looking for the object, may be {@code null}
2461 * @param valueToFind the object to find
2462 * @return the last index of the value within the array,
2463 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2464 */
2465 public static int lastIndexOf(final byte[] array, final byte valueToFind) {
2466 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2467 }
2468
2469 /**
2470 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2471 *
2472 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2473 *
2474 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2475 * array length will search from the end of the array.</p>
2476 *
2477 * @param array the array to traverse for looking for the object, may be {@code null}
2478 * @param valueToFind the value to find
2479 * @param startIndex the start index to travers backwards from
2480 * @return the last index of the value within the array,
2481 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2482 */
2483 public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
2484 if (array == null) {
2485 return INDEX_NOT_FOUND;
2486 }
2487 if (startIndex < 0) {
2488 return INDEX_NOT_FOUND;
2489 } else if (startIndex >= array.length) {
2490 startIndex = array.length - 1;
2491 }
2492 for (int i = startIndex; i >= 0; i--) {
2493 if (valueToFind == array[i]) {
2494 return i;
2495 }
2496 }
2497 return INDEX_NOT_FOUND;
2498 }
2499
2500 /**
2501 * <p>Checks if the value is in the given array.</p>
2502 *
2503 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2504 *
2505 * @param array the array to search through
2506 * @param valueToFind the value to find
2507 * @return {@code true} if the array contains the object
2508 */
2509 public static boolean contains(final byte[] array, final byte valueToFind) {
2510 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2511 }
2512
2513 // double IndexOf
2514 //-----------------------------------------------------------------------
2515 /**
2516 * <p>Finds the index of the given value in the array.</p>
2517 *
2518 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2519 *
2520 * @param array the array to search through for the object, may be {@code null}
2521 * @param valueToFind the value to find
2522 * @return the index of the value within the array,
2523 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2524 */
2525 public static int indexOf(final double[] array, final double valueToFind) {
2526 return indexOf(array, valueToFind, 0);
2527 }
2528
2529 /**
2530 * <p>Finds the index of the given value within a given tolerance in the array.
2531 * This method will return the index of the first value which falls between the region
2532 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2533 *
2534 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2535 *
2536 * @param array the array to search through for the object, may be {@code null}
2537 * @param valueToFind the value to find
2538 * @param tolerance tolerance of the search
2539 * @return the index of the value within the array,
2540 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2541 */
2542 public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
2543 return indexOf(array, valueToFind, 0, tolerance);
2544 }
2545
2546 /**
2547 * <p>Finds the index of the given value in the array starting at the given index.</p>
2548 *
2549 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2550 *
2551 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2552 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2553 *
2554 * @param array the array to search through for the object, may be {@code null}
2555 * @param valueToFind the value to find
2556 * @param startIndex the index to start searching at
2557 * @return the index of the value within the array,
2558 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2559 */
2560 public static int indexOf(final double[] array, final double valueToFind, int startIndex) {
2561 if (ArrayUtils.isEmpty(array)) {
2562 return INDEX_NOT_FOUND;
2563 }
2564 if (startIndex < 0) {
2565 startIndex = 0;
2566 }
2567 for (int i = startIndex; i < array.length; i++) {
2568 if (valueToFind == array[i]) {
2569 return i;
2570 }
2571 }
2572 return INDEX_NOT_FOUND;
2573 }
2574
2575 /**
2576 * <p>Finds the index of the given value in the array starting at the given index.
2577 * This method will return the index of the first value which falls between the region
2578 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2579 *
2580 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2581 *
2582 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2583 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2584 *
2585 * @param array the array to search through for the object, may be {@code null}
2586 * @param valueToFind the value to find
2587 * @param startIndex the index to start searching at
2588 * @param tolerance tolerance of the search
2589 * @return the index of the value within the array,
2590 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2591 */
2592 public static int indexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2593 if (ArrayUtils.isEmpty(array)) {
2594 return INDEX_NOT_FOUND;
2595 }
2596 if (startIndex < 0) {
2597 startIndex = 0;
2598 }
2599 final double min = valueToFind - tolerance;
2600 final double max = valueToFind + tolerance;
2601 for (int i = startIndex; i < array.length; i++) {
2602 if (array[i] >= min && array[i] <= max) {
2603 return i;
2604 }
2605 }
2606 return INDEX_NOT_FOUND;
2607 }
2608
2609 /**
2610 * <p>Finds the last index of the given value within the array.</p>
2611 *
2612 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2613 *
2614 * @param array the array to travers backwords looking for the object, may be {@code null}
2615 * @param valueToFind the object to find
2616 * @return the last index of the value within the array,
2617 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2618 */
2619 public static int lastIndexOf(final double[] array, final double valueToFind) {
2620 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2621 }
2622
2623 /**
2624 * <p>Finds the last index of the given value within a given tolerance in the array.
2625 * This method will return the index of the last value which falls between the region
2626 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2627 *
2628 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2629 *
2630 * @param array the array to search through for the object, may be {@code null}
2631 * @param valueToFind the value to find
2632 * @param tolerance tolerance of the search
2633 * @return the index of the value within the array,
2634 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2635 */
2636 public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
2637 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
2638 }
2639
2640 /**
2641 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2642 *
2643 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2644 *
2645 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2646 * array length will search from the end of the array.</p>
2647 *
2648 * @param array the array to traverse for looking for the object, may be {@code null}
2649 * @param valueToFind the value to find
2650 * @param startIndex the start index to travers backwards from
2651 * @return the last index of the value within the array,
2652 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2653 */
2654 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
2655 if (ArrayUtils.isEmpty(array)) {
2656 return INDEX_NOT_FOUND;
2657 }
2658 if (startIndex < 0) {
2659 return INDEX_NOT_FOUND;
2660 } else if (startIndex >= array.length) {
2661 startIndex = array.length - 1;
2662 }
2663 for (int i = startIndex; i >= 0; i--) {
2664 if (valueToFind == array[i]) {
2665 return i;
2666 }
2667 }
2668 return INDEX_NOT_FOUND;
2669 }
2670
2671 /**
2672 * <p>Finds the last index of the given value in the array starting at the given index.
2673 * This method will return the index of the last value which falls between the region
2674 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2675 *
2676 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2677 *
2678 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2679 * array length will search from the end of the array.</p>
2680 *
2681 * @param array the array to traverse for looking for the object, may be {@code null}
2682 * @param valueToFind the value to find
2683 * @param startIndex the start index to travers backwards from
2684 * @param tolerance search for value within plus/minus this amount
2685 * @return the last index of the value within the array,
2686 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2687 */
2688 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2689 if (ArrayUtils.isEmpty(array)) {
2690 return INDEX_NOT_FOUND;
2691 }
2692 if (startIndex < 0) {
2693 return INDEX_NOT_FOUND;
2694 } else if (startIndex >= array.length) {
2695 startIndex = array.length - 1;
2696 }
2697 final double min = valueToFind - tolerance;
2698 final double max = valueToFind + tolerance;
2699 for (int i = startIndex; i >= 0; i--) {
2700 if (array[i] >= min && array[i] <= max) {
2701 return i;
2702 }
2703 }
2704 return INDEX_NOT_FOUND;
2705 }
2706
2707 /**
2708 * <p>Checks if the value is in the given array.</p>
2709 *
2710 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2711 *
2712 * @param array the array to search through
2713 * @param valueToFind the value to find
2714 * @return {@code true} if the array contains the object
2715 */
2716 public static boolean contains(final double[] array, final double valueToFind) {
2717 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2718 }
2719
2720 /**
2721 * <p>Checks if a value falling within the given tolerance is in the
2722 * given array. If the array contains a value within the inclusive range
2723 * defined by (value - tolerance) to (value + tolerance).</p>
2724 *
2725 * <p>The method returns {@code false} if a {@code null} array
2726 * is passed in.</p>
2727 *
2728 * @param array the array to search
2729 * @param valueToFind the value to find
2730 * @param tolerance the array contains the tolerance of the search
2731 * @return true if value falling within tolerance is in array
2732 */
2733 public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
2734 return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
2735 }
2736
2737 // float IndexOf
2738 //-----------------------------------------------------------------------
2739 /**
2740 * <p>Finds the index of the given value in the array.</p>
2741 *
2742 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2743 *
2744 * @param array the array to search through for the object, may be {@code null}
2745 * @param valueToFind the value to find
2746 * @return the index of the value within the array,
2747 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2748 */
2749 public static int indexOf(final float[] array, final float valueToFind) {
2750 return indexOf(array, valueToFind, 0);
2751 }
2752
2753 /**
2754 * <p>Finds the index of the given value in the array starting at the given index.</p>
2755 *
2756 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2757 *
2758 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2759 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2760 *
2761 * @param array the array to search through for the object, may be {@code null}
2762 * @param valueToFind the value to find
2763 * @param startIndex the index to start searching at
2764 * @return the index of the value within the array,
2765 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2766 */
2767 public static int indexOf(final float[] array, final float valueToFind, int startIndex) {
2768 if (ArrayUtils.isEmpty(array)) {
2769 return INDEX_NOT_FOUND;
2770 }
2771 if (startIndex < 0) {
2772 startIndex = 0;
2773 }
2774 for (int i = startIndex; i < array.length; i++) {
2775 if (valueToFind == array[i]) {
2776 return i;
2777 }
2778 }
2779 return INDEX_NOT_FOUND;
2780 }
2781
2782 /**
2783 * <p>Finds the last index of the given value within the array.</p>
2784 *
2785 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2786 *
2787 * @param array the array to travers backwords looking for the object, may be {@code null}
2788 * @param valueToFind the object to find
2789 * @return the last index of the value within the array,
2790 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2791 */
2792 public static int lastIndexOf(final float[] array, final float valueToFind) {
2793 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2794 }
2795
2796 /**
2797 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2798 *
2799 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2800 *
2801 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2802 * array length will search from the end of the array.</p>
2803 *
2804 * @param array the array to traverse for looking for the object, may be {@code null}
2805 * @param valueToFind the value to find
2806 * @param startIndex the start index to travers backwards from
2807 * @return the last index of the value within the array,
2808 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2809 */
2810 public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
2811 if (ArrayUtils.isEmpty(array)) {
2812 return INDEX_NOT_FOUND;
2813 }
2814 if (startIndex < 0) {
2815 return INDEX_NOT_FOUND;
2816 } else if (startIndex >= array.length) {
2817 startIndex = array.length - 1;
2818 }
2819 for (int i = startIndex; i >= 0; i--) {
2820 if (valueToFind == array[i]) {
2821 return i;
2822 }
2823 }
2824 return INDEX_NOT_FOUND;
2825 }
2826
2827 /**
2828 * <p>Checks if the value is in the given array.</p>
2829 *
2830 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2831 *
2832 * @param array the array to search through
2833 * @param valueToFind the value to find
2834 * @return {@code true} if the array contains the object
2835 */
2836 public static boolean contains(final float[] array, final float valueToFind) {
2837 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2838 }
2839
2840 // boolean IndexOf
2841 //-----------------------------------------------------------------------
2842 /**
2843 * <p>Finds the index of the given value in the array.</p>
2844 *
2845 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2846 *
2847 * @param array the array to search through for the object, may be {@code null}
2848 * @param valueToFind the value to find
2849 * @return the index of the value within the array,
2850 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2851 */
2852 public static int indexOf(final boolean[] array, final boolean valueToFind) {
2853 return indexOf(array, valueToFind, 0);
2854 }
2855
2856 /**
2857 * <p>Finds the index of the given value in the array starting at the given index.</p>
2858 *
2859 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2860 *
2861 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2862 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2863 *
2864 * @param array the array to search through for the object, may be {@code null}
2865 * @param valueToFind the value to find
2866 * @param startIndex the index to start searching at
2867 * @return the index of the value within the array,
2868 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
2869 * array input
2870 */
2871 public static int indexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
2872 if (ArrayUtils.isEmpty(array)) {
2873 return INDEX_NOT_FOUND;
2874 }
2875 if (startIndex < 0) {
2876 startIndex = 0;
2877 }
2878 for (int i = startIndex; i < array.length; i++) {
2879 if (valueToFind == array[i]) {
2880 return i;
2881 }
2882 }
2883 return INDEX_NOT_FOUND;
2884 }
2885
2886 /**
2887 * <p>Finds the last index of the given value within the array.</p>
2888 *
2889 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
2890 * {@code null} array input.</p>
2891 *
2892 * @param array the array to travers backwords looking for the object, may be {@code null}
2893 * @param valueToFind the object to find
2894 * @return the last index of the value within the array,
2895 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2896 */
2897 public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
2898 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2899 }
2900
2901 /**
2902 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2903 *
2904 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2905 *
2906 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
2907 * the array length will search from the end of the array.</p>
2908 *
2909 * @param array the array to traverse for looking for the object, may be {@code null}
2910 * @param valueToFind the value to find
2911 * @param startIndex the start index to travers backwards from
2912 * @return the last index of the value within the array,
2913 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2914 */
2915 public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
2916 if (ArrayUtils.isEmpty(array)) {
2917 return INDEX_NOT_FOUND;
2918 }
2919 if (startIndex < 0) {
2920 return INDEX_NOT_FOUND;
2921 } else if (startIndex >= array.length) {
2922 startIndex = array.length - 1;
2923 }
2924 for (int i = startIndex; i >= 0; i--) {
2925 if (valueToFind == array[i]) {
2926 return i;
2927 }
2928 }
2929 return INDEX_NOT_FOUND;
2930 }
2931
2932 /**
2933 * <p>Checks if the value is in the given array.</p>
2934 *
2935 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2936 *
2937 * @param array the array to search through
2938 * @param valueToFind the value to find
2939 * @return {@code true} if the array contains the object
2940 */
2941 public static boolean contains(final boolean[] array, final boolean valueToFind) {
2942 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2943 }
2944
2945 // Primitive/Object array converters
2946 // ----------------------------------------------------------------------
2947
2948 // Character array converters
2949 // ----------------------------------------------------------------------
2950 /**
2951 * <p>Converts an array of object Characters to primitives.</p>
2952 *
2953 * <p>This method returns {@code null} for a {@code null} input array.</p>
2954 *
2955 * @param array a {@code Character} array, may be {@code null}
2956 * @return a {@code char} array, {@code null} if null array input
2957 * @throws NullPointerException if array content is {@code null}
2958 */
2959 public static char[] toPrimitive(final Character[] array) {
2960 if (array == null) {
2961 return null;
2962 } else if (array.length == 0) {
2963 return EMPTY_CHAR_ARRAY;
2964 }
2965 final char[] result = new char[array.length];
2966 for (int i = 0; i < array.length; i++) {
2967 result[i] = array[i].charValue();
2968 }
2969 return result;
2970 }
2971
2972 /**
2973 * <p>Converts an array of object Character to primitives handling {@code null}.</p>
2974 *
2975 * <p>This method returns {@code null} for a {@code null} input array.</p>
2976 *
2977 * @param array a {@code Character} array, may be {@code null}
2978 * @param valueForNull the value to insert if {@code null} found
2979 * @return a {@code char} array, {@code null} if null array input
2980 */
2981 public static char[] toPrimitive(final Character[] array, final char valueForNull) {
2982 if (array == null) {
2983 return null;
2984 } else if (array.length == 0) {
2985 return EMPTY_CHAR_ARRAY;
2986 }
2987 final char[] result = new char[array.length];
2988 for (int i = 0; i < array.length; i++) {
2989 final Character b = array[i];
2990 result[i] = (b == null ? valueForNull : b.charValue());
2991 }
2992 return result;
2993 }
2994
2995 /**
2996 * <p>Converts an array of primitive chars to objects.</p>
2997 *
2998 * <p>This method returns {@code null} for a {@code null} input array.</p>
2999 *
3000 * @param array a {@code char} array
3001 * @return a {@code Character} array, {@code null} if null array input
3002 */
3003 public static Character[] toObject(final char[] array) {
3004 if (array == null) {
3005 return null;
3006 } else if (array.length == 0) {
3007 return EMPTY_CHARACTER_OBJECT_ARRAY;
3008 }
3009 final Character[] result = new Character[array.length];
3010 for (int i = 0; i < array.length; i++) {
3011 result[i] = Character.valueOf(array[i]);
3012 }
3013 return result;
3014 }
3015
3016 // Long array converters
3017 // ----------------------------------------------------------------------
3018 /**
3019 * <p>Converts an array of object Longs to primitives.</p>
3020 *
3021 * <p>This method returns {@code null} for a {@code null} input array.</p>
3022 *
3023 * @param array a {@code Long} array, may be {@code null}
3024 * @return a {@code long} array, {@code null} if null array input
3025 * @throws NullPointerException if array content is {@code null}
3026 */
3027 public static long[] toPrimitive(final Long[] array) {
3028 if (array == null) {
3029 return null;
3030 } else if (array.length == 0) {
3031 return EMPTY_LONG_ARRAY;
3032 }
3033 final long[] result = new long[array.length];
3034 for (int i = 0; i < array.length; i++) {
3035 result[i] = array[i].longValue();
3036 }
3037 return result;
3038 }
3039
3040 /**
3041 * <p>Converts an array of object Long to primitives handling {@code null}.</p>
3042 *
3043 * <p>This method returns {@code null} for a {@code null} input array.</p>
3044 *
3045 * @param array a {@code Long} array, may be {@code null}
3046 * @param valueForNull the value to insert if {@code null} found
3047 * @return a {@code long} array, {@code null} if null array input
3048 */
3049 public static long[] toPrimitive(final Long[] array, final long valueForNull) {
3050 if (array == null) {
3051 return null;
3052 } else if (array.length == 0) {
3053 return EMPTY_LONG_ARRAY;
3054 }
3055 final long[] result = new long[array.length];
3056 for (int i = 0; i < array.length; i++) {
3057 final Long b = array[i];
3058 result[i] = (b == null ? valueForNull : b.longValue());
3059 }
3060 return result;
3061 }
3062
3063 /**
3064 * <p>Converts an array of primitive longs to objects.</p>
3065 *
3066 * <p>This method returns {@code null} for a {@code null} input array.</p>
3067 *
3068 * @param array a {@code long} array
3069 * @return a {@code Long} array, {@code null} if null array input
3070 */
3071 public static Long[] toObject(final long[] array) {
3072 if (array == null) {
3073 return null;
3074 } else if (array.length == 0) {
3075 return EMPTY_LONG_OBJECT_ARRAY;
3076 }
3077 final Long[] result = new Long[array.length];
3078 for (int i = 0; i < array.length; i++) {
3079 result[i] = Long.valueOf(array[i]);
3080 }
3081 return result;
3082 }
3083
3084 // Int array converters
3085 // ----------------------------------------------------------------------
3086 /**
3087 * <p>Converts an array of object Integers to primitives.</p>
3088 *
3089 * <p>This method returns {@code null} for a {@code null} input array.</p>
3090 *
3091 * @param array a {@code Integer} array, may be {@code null}
3092 * @return an {@code int} array, {@code null} if null array input
3093 * @throws NullPointerException if array content is {@code null}
3094 */
3095 public static int[] toPrimitive(final Integer[] array) {
3096 if (array == null) {
3097 return null;
3098 } else if (array.length == 0) {
3099 return EMPTY_INT_ARRAY;
3100 }
3101 final int[] result = new int[array.length];
3102 for (int i = 0; i < array.length; i++) {
3103 result[i] = array[i].intValue();
3104 }
3105 return result;
3106 }
3107
3108 /**
3109 * <p>Converts an array of object Integer to primitives handling {@code null}.</p>
3110 *
3111 * <p>This method returns {@code null} for a {@code null} input array.</p>
3112 *
3113 * @param array a {@code Integer} array, may be {@code null}
3114 * @param valueForNull the value to insert if {@code null} found
3115 * @return an {@code int} array, {@code null} if null array input
3116 */
3117 public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
3118 if (array == null) {
3119 return null;
3120 } else if (array.length == 0) {
3121 return EMPTY_INT_ARRAY;
3122 }
3123 final int[] result = new int[array.length];
3124 for (int i = 0; i < array.length; i++) {
3125 final Integer b = array[i];
3126 result[i] = (b == null ? valueForNull : b.intValue());
3127 }
3128 return result;
3129 }
3130
3131 /**
3132 * <p>Converts an array of primitive ints to objects.</p>
3133 *
3134 * <p>This method returns {@code null} for a {@code null} input array.</p>
3135 *
3136 * @param array an {@code int} array
3137 * @return an {@code Integer} array, {@code null} if null array input
3138 */
3139 public static Integer[] toObject(final int[] array) {
3140 if (array == null) {
3141 return null;
3142 } else if (array.length == 0) {
3143 return EMPTY_INTEGER_OBJECT_ARRAY;
3144 }
3145 final Integer[] result = new Integer[array.length];
3146 for (int i = 0; i < array.length; i++) {
3147 result[i] = Integer.valueOf(array[i]);
3148 }
3149 return result;
3150 }
3151
3152 // Short array converters
3153 // ----------------------------------------------------------------------
3154 /**
3155 * <p>Converts an array of object Shorts to primitives.</p>
3156 *
3157 * <p>This method returns {@code null} for a {@code null} input array.</p>
3158 *
3159 * @param array a {@code Short} array, may be {@code null}
3160 * @return a {@code byte} array, {@code null} if null array input
3161 * @throws NullPointerException if array content is {@code null}
3162 */
3163 public static short[] toPrimitive(final Short[] array) {
3164 if (array == null) {
3165 return null;
3166 } else if (array.length == 0) {
3167 return EMPTY_SHORT_ARRAY;
3168 }
3169 final short[] result = new short[array.length];
3170 for (int i = 0; i < array.length; i++) {
3171 result[i] = array[i].shortValue();
3172 }
3173 return result;
3174 }
3175
3176 /**
3177 * <p>Converts an array of object Short to primitives handling {@code null}.</p>
3178 *
3179 * <p>This method returns {@code null} for a {@code null} input array.</p>
3180 *
3181 * @param array a {@code Short} array, may be {@code null}
3182 * @param valueForNull the value to insert if {@code null} found
3183 * @return a {@code byte} array, {@code null} if null array input
3184 */
3185 public static short[] toPrimitive(final Short[] array, final short valueForNull) {
3186 if (array == null) {
3187 return null;
3188 } else if (array.length == 0) {
3189 return EMPTY_SHORT_ARRAY;
3190 }
3191 final short[] result = new short[array.length];
3192 for (int i = 0; i < array.length; i++) {
3193 final Short b = array[i];
3194 result[i] = (b == null ? valueForNull : b.shortValue());
3195 }
3196 return result;
3197 }
3198
3199 /**
3200 * <p>Converts an array of primitive shorts to objects.</p>
3201 *
3202 * <p>This method returns {@code null} for a {@code null} input array.</p>
3203 *
3204 * @param array a {@code short} array
3205 * @return a {@code Short} array, {@code null} if null array input
3206 */
3207 public static Short[] toObject(final short[] array) {
3208 if (array == null) {
3209 return null;
3210 } else if (array.length == 0) {
3211 return EMPTY_SHORT_OBJECT_ARRAY;
3212 }
3213 final Short[] result = new Short[array.length];
3214 for (int i = 0; i < array.length; i++) {
3215 result[i] = Short.valueOf(array[i]);
3216 }
3217 return result;
3218 }
3219
3220 // Byte array converters
3221 // ----------------------------------------------------------------------
3222 /**
3223 * <p>Converts an array of object Bytes to primitives.</p>
3224 *
3225 * <p>This method returns {@code null} for a {@code null} input array.</p>
3226 *
3227 * @param array a {@code Byte} array, may be {@code null}
3228 * @return a {@code byte} array, {@code null} if null array input
3229 * @throws NullPointerException if array content is {@code null}
3230 */
3231 public static byte[] toPrimitive(final Byte[] array) {
3232 if (array == null) {
3233 return null;
3234 } else if (array.length == 0) {
3235 return EMPTY_BYTE_ARRAY;
3236 }
3237 final byte[] result = new byte[array.length];
3238 for (int i = 0; i < array.length; i++) {
3239 result[i] = array[i].byteValue();
3240 }
3241 return result;
3242 }
3243
3244 /**
3245 * <p>Converts an array of object Bytes to primitives handling {@code null}.</p>
3246 *
3247 * <p>This method returns {@code null} for a {@code null} input array.</p>
3248 *
3249 * @param array a {@code Byte} array, may be {@code null}
3250 * @param valueForNull the value to insert if {@code null} found
3251 * @return a {@code byte} array, {@code null} if null array input
3252 */
3253 public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
3254 if (array == null) {
3255 return null;
3256 } else if (array.length == 0) {
3257 return EMPTY_BYTE_ARRAY;
3258 }
3259 final byte[] result = new byte[array.length];
3260 for (int i = 0; i < array.length; i++) {
3261 final Byte b = array[i];
3262 result[i] = (b == null ? valueForNull : b.byteValue());
3263 }
3264 return result;
3265 }
3266
3267 /**
3268 * <p>Converts an array of primitive bytes to objects.</p>
3269 *
3270 * <p>This method returns {@code null} for a {@code null} input array.</p>
3271 *
3272 * @param array a {@code byte} array
3273 * @return a {@code Byte} array, {@code null} if null array input
3274 */
3275 public static Byte[] toObject(final byte[] array) {
3276 if (array == null) {
3277 return null;
3278 } else if (array.length == 0) {
3279 return EMPTY_BYTE_OBJECT_ARRAY;
3280 }
3281 final Byte[] result = new Byte[array.length];
3282 for (int i = 0; i < array.length; i++) {
3283 result[i] = Byte.valueOf(array[i]);
3284 }
3285 return result;
3286 }
3287
3288 // Double array converters
3289 // ----------------------------------------------------------------------
3290 /**
3291 * <p>Converts an array of object Doubles to primitives.</p>
3292 *
3293 * <p>This method returns {@code null} for a {@code null} input array.</p>
3294 *
3295 * @param array a {@code Double} array, may be {@code null}
3296 * @return a {@code double} array, {@code null} if null array input
3297 * @throws NullPointerException if array content is {@code null}
3298 */
3299 public static double[] toPrimitive(final Double[] array) {
3300 if (array == null) {
3301 return null;
3302 } else if (array.length == 0) {
3303 return EMPTY_DOUBLE_ARRAY;
3304 }
3305 final double[] result = new double[array.length];
3306 for (int i = 0; i < array.length; i++) {
3307 result[i] = array[i].doubleValue();
3308 }
3309 return result;
3310 }
3311
3312 /**
3313 * <p>Converts an array of object Doubles to primitives handling {@code null}.</p>
3314 *
3315 * <p>This method returns {@code null} for a {@code null} input array.</p>
3316 *
3317 * @param array a {@code Double} array, may be {@code null}
3318 * @param valueForNull the value to insert if {@code null} found
3319 * @return a {@code double} array, {@code null} if null array input
3320 */
3321 public static double[] toPrimitive(final Double[] array, final double valueForNull) {
3322 if (array == null) {
3323 return null;
3324 } else if (array.length == 0) {
3325 return EMPTY_DOUBLE_ARRAY;
3326 }
3327 final double[] result = new double[array.length];
3328 for (int i = 0; i < array.length; i++) {
3329 final Double b = array[i];
3330 result[i] = (b == null ? valueForNull : b.doubleValue());
3331 }
3332 return result;
3333 }
3334
3335 /**
3336 * <p>Converts an array of primitive doubles to objects.</p>
3337 *
3338 * <p>This method returns {@code null} for a {@code null} input array.</p>
3339 *
3340 * @param array a {@code double} array
3341 * @return a {@code Double} array, {@code null} if null array input
3342 */
3343 public static Double[] toObject(final double[] array) {
3344 if (array == null) {
3345 return null;
3346 } else if (array.length == 0) {
3347 return EMPTY_DOUBLE_OBJECT_ARRAY;
3348 }
3349 final Double[] result = new Double[array.length];
3350 for (int i = 0; i < array.length; i++) {
3351 result[i] = Double.valueOf(array[i]);
3352 }
3353 return result;
3354 }
3355
3356 // Float array converters
3357 // ----------------------------------------------------------------------
3358 /**
3359 * <p>Converts an array of object Floats to primitives.</p>
3360 *
3361 * <p>This method returns {@code null} for a {@code null} input array.</p>
3362 *
3363 * @param array a {@code Float} array, may be {@code null}
3364 * @return a {@code float} array, {@code null} if null array input
3365 * @throws NullPointerException if array content is {@code null}
3366 */
3367 public static float[] toPrimitive(final Float[] array) {
3368 if (array == null) {
3369 return null;
3370 } else if (array.length == 0) {
3371 return EMPTY_FLOAT_ARRAY;
3372 }
3373 final float[] result = new float[array.length];
3374 for (int i = 0; i < array.length; i++) {
3375 result[i] = array[i].floatValue();
3376 }
3377 return result;
3378 }
3379
3380 /**
3381 * <p>Converts an array of object Floats to primitives handling {@code null}.</p>
3382 *
3383 * <p>This method returns {@code null} for a {@code null} input array.</p>
3384 *
3385 * @param array a {@code Float} array, may be {@code null}
3386 * @param valueForNull the value to insert if {@code null} found
3387 * @return a {@code float} array, {@code null} if null array input
3388 */
3389 public static float[] toPrimitive(final Float[] array, final float valueForNull) {
3390 if (array == null) {
3391 return null;
3392 } else if (array.length == 0) {
3393 return EMPTY_FLOAT_ARRAY;
3394 }
3395 final float[] result = new float[array.length];
3396 for (int i = 0; i < array.length; i++) {
3397 final Float b = array[i];
3398 result[i] = (b == null ? valueForNull : b.floatValue());
3399 }
3400 return result;
3401 }
3402
3403 /**
3404 * <p>Converts an array of primitive floats to objects.</p>
3405 *
3406 * <p>This method returns {@code null} for a {@code null} input array.</p>
3407 *
3408 * @param array a {@code float} array
3409 * @return a {@code Float} array, {@code null} if null array input
3410 */
3411 public static Float[] toObject(final float[] array) {
3412 if (array == null) {
3413 return null;
3414 } else if (array.length == 0) {
3415 return EMPTY_FLOAT_OBJECT_ARRAY;
3416 }
3417 final Float[] result = new Float[array.length];
3418 for (int i = 0; i < array.length; i++) {
3419 result[i] = Float.valueOf(array[i]);
3420 }
3421 return result;
3422 }
3423
3424 // Boolean array converters
3425 // ----------------------------------------------------------------------
3426 /**
3427 * <p>Converts an array of object Booleans to primitives.</p>
3428 *
3429 * <p>This method returns {@code null} for a {@code null} input array.</p>
3430 *
3431 * @param array a {@code Boolean} array, may be {@code null}
3432 * @return a {@code boolean} array, {@code null} if null array input
3433 * @throws NullPointerException if array content is {@code null}
3434 */
3435 public static boolean[] toPrimitive(final Boolean[] array) {
3436 if (array == null) {
3437 return null;
3438 } else if (array.length == 0) {
3439 return EMPTY_BOOLEAN_ARRAY;
3440 }
3441 final boolean[] result = new boolean[array.length];
3442 for (int i = 0; i < array.length; i++) {
3443 result[i] = array[i].booleanValue();
3444 }
3445 return result;
3446 }
3447
3448 /**
3449 * <p>Converts an array of object Booleans to primitives handling {@code null}.</p>
3450 *
3451 * <p>This method returns {@code null} for a {@code null} input array.</p>
3452 *
3453 * @param array a {@code Boolean} array, may be {@code null}
3454 * @param valueForNull the value to insert if {@code null} found
3455 * @return a {@code boolean} array, {@code null} if null array input
3456 */
3457 public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
3458 if (array == null) {
3459 return null;
3460 } else if (array.length == 0) {
3461 return EMPTY_BOOLEAN_ARRAY;
3462 }
3463 final boolean[] result = new boolean[array.length];
3464 for (int i = 0; i < array.length; i++) {
3465 final Boolean b = array[i];
3466 result[i] = (b == null ? valueForNull : b.booleanValue());
3467 }
3468 return result;
3469 }
3470
3471 /**
3472 * <p>Converts an array of primitive booleans to objects.</p>
3473 *
3474 * <p>This method returns {@code null} for a {@code null} input array.</p>
3475 *
3476 * @param array a {@code boolean} array
3477 * @return a {@code Boolean} array, {@code null} if null array input
3478 */
3479 public static Boolean[] toObject(final boolean[] array) {
3480 if (array == null) {
3481 return null;
3482 } else if (array.length == 0) {
3483 return EMPTY_BOOLEAN_OBJECT_ARRAY;
3484 }
3485 final Boolean[] result = new Boolean[array.length];
3486 for (int i = 0; i < array.length; i++) {
3487 result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
3488 }
3489 return result;
3490 }
3491
3492 // ----------------------------------------------------------------------
3493 /**
3494 * <p>Checks if an array of Objects is empty or {@code null}.</p>
3495 *
3496 * @param array the array to test
3497 * @return {@code true} if the array is empty or {@code null}
3498 * @since 2.1
3499 */
3500 public static boolean isEmpty(final Object[] array) {
3501 return array == null || array.length == 0;
3502 }
3503
3504 /**
3505 * <p>Checks if an array of primitive longs is empty or {@code null}.</p>
3506 *
3507 * @param array the array to test
3508 * @return {@code true} if the array is empty or {@code null}
3509 * @since 2.1
3510 */
3511 public static boolean isEmpty(final long[] array) {
3512 return array == null || array.length == 0;
3513 }
3514
3515 /**
3516 * <p>Checks if an array of primitive ints is empty or {@code null}.</p>
3517 *
3518 * @param array the array to test
3519 * @return {@code true} if the array is empty or {@code null}
3520 * @since 2.1
3521 */
3522 public static boolean isEmpty(final int[] array) {
3523 return array == null || array.length == 0;
3524 }
3525
3526 /**
3527 * <p>Checks if an array of primitive shorts is empty or {@code null}.</p>
3528 *
3529 * @param array the array to test
3530 * @return {@code true} if the array is empty or {@code null}
3531 * @since 2.1
3532 */
3533 public static boolean isEmpty(final short[] array) {
3534 return array == null || array.length == 0;
3535 }
3536
3537 /**
3538 * <p>Checks if an array of primitive chars is empty or {@code null}.</p>
3539 *
3540 * @param array the array to test
3541 * @return {@code true} if the array is empty or {@code null}
3542 * @since 2.1
3543 */
3544 public static boolean isEmpty(final char[] array) {
3545 return array == null || array.length == 0;
3546 }
3547
3548 /**
3549 * <p>Checks if an array of primitive bytes is empty or {@code null}.</p>
3550 *
3551 * @param array the array to test
3552 * @return {@code true} if the array is empty or {@code null}
3553 * @since 2.1
3554 */
3555 public static boolean isEmpty(final byte[] array) {
3556 return array == null || array.length == 0;
3557 }
3558
3559 /**
3560 * <p>Checks if an array of primitive doubles is empty or {@code null}.</p>
3561 *
3562 * @param array the array to test
3563 * @return {@code true} if the array is empty or {@code null}
3564 * @since 2.1
3565 */
3566 public static boolean isEmpty(final double[] array) {
3567 return array == null || array.length == 0;
3568 }
3569
3570 /**
3571 * <p>Checks if an array of primitive floats is empty or {@code null}.</p>
3572 *
3573 * @param array the array to test
3574 * @return {@code true} if the array is empty or {@code null}
3575 * @since 2.1
3576 */
3577 public static boolean isEmpty(final float[] array) {
3578 return array == null || array.length == 0;
3579 }
3580
3581 /**
3582 * <p>Checks if an array of primitive booleans is empty or {@code null}.</p>
3583 *
3584 * @param array the array to test
3585 * @return {@code true} if the array is empty or {@code null}
3586 * @since 2.1
3587 */
3588 public static boolean isEmpty(final boolean[] array) {
3589 return array == null || array.length == 0;
3590 }
3591
3592 // ----------------------------------------------------------------------
3593 /**
3594 * <p>Checks if an array of Objects is not empty or not {@code null}.</p>
3595 *
3596 * @param <T> the component type of the array
3597 * @param array the array to test
3598 * @return {@code true} if the array is not empty or not {@code null}
3599 * @since 2.5
3600 */
3601 public static <T> boolean isNotEmpty(final T[] array) {
3602 return (array != null && array.length != 0);
3603 }
3604
3605 /**
3606 * <p>Checks if an array of primitive longs is not empty or not {@code null}.</p>
3607 *
3608 * @param array the array to test
3609 * @return {@code true} if the array is not empty or not {@code null}
3610 * @since 2.5
3611 */
3612 public static boolean isNotEmpty(final long[] array) {
3613 return (array != null && array.length != 0);
3614 }
3615
3616 /**
3617 * <p>Checks if an array of primitive ints is not empty or not {@code null}.</p>
3618 *
3619 * @param array the array to test
3620 * @return {@code true} if the array is not empty or not {@code null}
3621 * @since 2.5
3622 */
3623 public static boolean isNotEmpty(final int[] array) {
3624 return (array != null && array.length != 0);
3625 }
3626
3627 /**
3628 * <p>Checks if an array of primitive shorts is not empty or not {@code null}.</p>
3629 *
3630 * @param array the array to test
3631 * @return {@code true} if the array is not empty or not {@code null}
3632 * @since 2.5
3633 */
3634 public static boolean isNotEmpty(final short[] array) {
3635 return (array != null && array.length != 0);
3636 }
3637
3638 /**
3639 * <p>Checks if an array of primitive chars is not empty or not {@code null}.</p>
3640 *
3641 * @param array the array to test
3642 * @return {@code true} if the array is not empty or not {@code null}
3643 * @since 2.5
3644 */
3645 public static boolean isNotEmpty(final char[] array) {
3646 return (array != null && array.length != 0);
3647 }
3648
3649 /**
3650 * <p>Checks if an array of primitive bytes is not empty or not {@code null}.</p>
3651 *
3652 * @param array the array to test
3653 * @return {@code true} if the array is not empty or not {@code null}
3654 * @since 2.5
3655 */
3656 public static boolean isNotEmpty(final byte[] array) {
3657 return (array != null && array.length != 0);
3658 }
3659
3660 /**
3661 * <p>Checks if an array of primitive doubles is not empty or not {@code null}.</p>
3662 *
3663 * @param array the array to test
3664 * @return {@code true} if the array is not empty or not {@code null}
3665 * @since 2.5
3666 */
3667 public static boolean isNotEmpty(final double[] array) {
3668 return (array != null && array.length != 0);
3669 }
3670
3671 /**
3672 * <p>Checks if an array of primitive floats is not empty or not {@code null}.</p>
3673 *
3674 * @param array the array to test
3675 * @return {@code true} if the array is not empty or not {@code null}
3676 * @since 2.5
3677 */
3678 public static boolean isNotEmpty(final float[] array) {
3679 return (array != null && array.length != 0);
3680 }
3681
3682 /**
3683 * <p>Checks if an array of primitive booleans is not empty or not {@code null}.</p>
3684 *
3685 * @param array the array to test
3686 * @return {@code true} if the array is not empty or not {@code null}
3687 * @since 2.5
3688 */
3689 public static boolean isNotEmpty(final boolean[] array) {
3690 return (array != null && array.length != 0);
3691 }
3692
3693 /**
3694 * <p>Adds all the elements of the given arrays into a new array.</p>
3695 * <p>The new array contains all of the element of {@code array1} followed
3696 * by all of the elements {@code array2}. When an array is returned, it is always
3697 * a new array.</p>
3698 *
3699 * <pre>
3700 * ArrayUtils.addAll(null, null) = null
3701 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3702 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3703 * ArrayUtils.addAll([], []) = []
3704 * ArrayUtils.addAll([null], [null]) = [null, null]
3705 * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
3706 * </pre>
3707 *
3708 * @param <T> the component type of the array
3709 * @param array1 the first array whose elements are added to the new array, may be {@code null}
3710 * @param array2 the second array whose elements are added to the new array, may be {@code null}
3711 * @return The new array, {@code null} if both arrays are {@code null}.
3712 * The type of the new array is the type of the first array,
3713 * unless the first array is null, in which case the type is the same as the second array.
3714 * @since 2.1
3715 * @throws IllegalArgumentException if the array types are incompatible
3716 */
3717 public static <T> T[] addAll(final T[] array1, final T... array2) {
3718 if (array1 == null) {
3719 return clone(array2);
3720 } else if (array2 == null) {
3721 return clone(array1);
3722 }
3723 final Class<?> type1 = array1.getClass().getComponentType();
3724 @SuppressWarnings("unchecked") // OK, because array is of type T
3725 final
3726 T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
3727 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3728 try {
3729 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3730 } catch (final ArrayStoreException ase) {
3731 // Check if problem was due to incompatible types
3732 /*
3733 * We do this here, rather than before the copy because:
3734 * - it would be a wasted check most of the time
3735 * - safer, in case check turns out to be too strict
3736 */
3737 final Class<?> type2 = array2.getClass().getComponentType();
3738 if (!type1.isAssignableFrom(type2)){
3739 throw new IllegalArgumentException("Cannot store "+type2.getName()+" in an array of "
3740 +type1.getName(), ase);
3741 }
3742 throw ase; // No, so rethrow original
3743 }
3744 return joinedArray;
3745 }
3746
3747 /**
3748 * <p>Adds all the elements of the given arrays into a new array.</p>
3749 * <p>The new array contains all of the element of {@code array1} followed
3750 * by all of the elements {@code array2}. When an array is returned, it is always
3751 * a new array.</p>
3752 *
3753 * <pre>
3754 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3755 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3756 * ArrayUtils.addAll([], []) = []
3757 * </pre>
3758 *
3759 * @param array1 the first array whose elements are added to the new array.
3760 * @param array2 the second array whose elements are added to the new array.
3761 * @return The new boolean[] array.
3762 * @since 2.1
3763 */
3764 public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
3765 if (array1 == null) {
3766 return clone(array2);
3767 } else if (array2 == null) {
3768 return clone(array1);
3769 }
3770 final boolean[] joinedArray = new boolean[array1.length + array2.length];
3771 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3772 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3773 return joinedArray;
3774 }
3775
3776 /**
3777 * <p>Adds all the elements of the given arrays into a new array.</p>
3778 * <p>The new array contains all of the element of {@code array1} followed
3779 * by all of the elements {@code array2}. When an array is returned, it is always
3780 * a new array.</p>
3781 *
3782 * <pre>
3783 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3784 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3785 * ArrayUtils.addAll([], []) = []
3786 * </pre>
3787 *
3788 * @param array1 the first array whose elements are added to the new array.
3789 * @param array2 the second array whose elements are added to the new array.
3790 * @return The new char[] array.
3791 * @since 2.1
3792 */
3793 public static char[] addAll(final char[] array1, final char... array2) {
3794 if (array1 == null) {
3795 return clone(array2);
3796 } else if (array2 == null) {
3797 return clone(array1);
3798 }
3799 final char[] joinedArray = new char[array1.length + array2.length];
3800 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3801 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3802 return joinedArray;
3803 }
3804
3805 /**
3806 * <p>Adds all the elements of the given arrays into a new array.</p>
3807 * <p>The new array contains all of the element of {@code array1} followed
3808 * by all of the elements {@code array2}. When an array is returned, it is always
3809 * a new array.</p>
3810 *
3811 * <pre>
3812 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3813 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3814 * ArrayUtils.addAll([], []) = []
3815 * </pre>
3816 *
3817 * @param array1 the first array whose elements are added to the new array.
3818 * @param array2 the second array whose elements are added to the new array.
3819 * @return The new byte[] array.
3820 * @since 2.1
3821 */
3822 public static byte[] addAll(final byte[] array1, final byte... array2) {
3823 if (array1 == null) {
3824 return clone(array2);
3825 } else if (array2 == null) {
3826 return clone(array1);
3827 }
3828 final byte[] joinedArray = new byte[array1.length + array2.length];
3829 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3830 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3831 return joinedArray;
3832 }
3833
3834 /**
3835 * <p>Adds all the elements of the given arrays into a new array.</p>
3836 * <p>The new array contains all of the element of {@code array1} followed
3837 * by all of the elements {@code array2}. When an array is returned, it is always
3838 * a new array.</p>
3839 *
3840 * <pre>
3841 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3842 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3843 * ArrayUtils.addAll([], []) = []
3844 * </pre>
3845 *
3846 * @param array1 the first array whose elements are added to the new array.
3847 * @param array2 the second array whose elements are added to the new array.
3848 * @return The new short[] array.
3849 * @since 2.1
3850 */
3851 public static short[] addAll(final short[] array1, final short... array2) {
3852 if (array1 == null) {
3853 return clone(array2);
3854 } else if (array2 == null) {
3855 return clone(array1);
3856 }
3857 final short[] joinedArray = new short[array1.length + array2.length];
3858 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3859 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3860 return joinedArray;
3861 }
3862
3863 /**
3864 * <p>Adds all the elements of the given arrays into a new array.</p>
3865 * <p>The new array contains all of the element of {@code array1} followed
3866 * by all of the elements {@code array2}. When an array is returned, it is always
3867 * a new array.</p>
3868 *
3869 * <pre>
3870 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3871 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3872 * ArrayUtils.addAll([], []) = []
3873 * </pre>
3874 *
3875 * @param array1 the first array whose elements are added to the new array.
3876 * @param array2 the second array whose elements are added to the new array.
3877 * @return The new int[] array.
3878 * @since 2.1
3879 */
3880 public static int[] addAll(final int[] array1, final int... array2) {
3881 if (array1 == null) {
3882 return clone(array2);
3883 } else if (array2 == null) {
3884 return clone(array1);
3885 }
3886 final int[] joinedArray = new int[array1.length + array2.length];
3887 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3888 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3889 return joinedArray;
3890 }
3891
3892 /**
3893 * <p>Adds all the elements of the given arrays into a new array.</p>
3894 * <p>The new array contains all of the element of {@code array1} followed
3895 * by all of the elements {@code array2}. When an array is returned, it is always
3896 * a new array.</p>
3897 *
3898 * <pre>
3899 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3900 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3901 * ArrayUtils.addAll([], []) = []
3902 * </pre>
3903 *
3904 * @param array1 the first array whose elements are added to the new array.
3905 * @param array2 the second array whose elements are added to the new array.
3906 * @return The new long[] array.
3907 * @since 2.1
3908 */
3909 public static long[] addAll(final long[] array1, final long... array2) {
3910 if (array1 == null) {
3911 return clone(array2);
3912 } else if (array2 == null) {
3913 return clone(array1);
3914 }
3915 final long[] joinedArray = new long[array1.length + array2.length];
3916 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3917 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3918 return joinedArray;
3919 }
3920
3921 /**
3922 * <p>Adds all the elements of the given arrays into a new array.</p>
3923 * <p>The new array contains all of the element of {@code array1} followed
3924 * by all of the elements {@code array2}. When an array is returned, it is always
3925 * a new array.</p>
3926 *
3927 * <pre>
3928 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3929 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3930 * ArrayUtils.addAll([], []) = []
3931 * </pre>
3932 *
3933 * @param array1 the first array whose elements are added to the new array.
3934 * @param array2 the second array whose elements are added to the new array.
3935 * @return The new float[] array.
3936 * @since 2.1
3937 */
3938 public static float[] addAll(final float[] array1, final float... array2) {
3939 if (array1 == null) {
3940 return clone(array2);
3941 } else if (array2 == null) {
3942 return clone(array1);
3943 }
3944 final float[] joinedArray = new float[array1.length + array2.length];
3945 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3946 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3947 return joinedArray;
3948 }
3949
3950 /**
3951 * <p>Adds all the elements of the given arrays into a new array.</p>
3952 * <p>The new array contains all of the element of {@code array1} followed
3953 * by all of the elements {@code array2}. When an array is returned, it is always
3954 * a new array.</p>
3955 *
3956 * <pre>
3957 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3958 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3959 * ArrayUtils.addAll([], []) = []
3960 * </pre>
3961 *
3962 * @param array1 the first array whose elements are added to the new array.
3963 * @param array2 the second array whose elements are added to the new array.
3964 * @return The new double[] array.
3965 * @since 2.1
3966 */
3967 public static double[] addAll(final double[] array1, final double... array2) {
3968 if (array1 == null) {
3969 return clone(array2);
3970 } else if (array2 == null) {
3971 return clone(array1);
3972 }
3973 final double[] joinedArray = new double[array1.length + array2.length];
3974 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3975 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3976 return joinedArray;
3977 }
3978
3979 /**
3980 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3981 *
3982 * <p>The new array contains the same elements of the input
3983 * array plus the given element in the last position. The component type of
3984 * the new array is the same as that of the input array.</p>
3985 *
3986 * <p>If the input array is {@code null}, a new one element array is returned
3987 * whose component type is the same as the element, unless the element itself is null,
3988 * in which case the return type is Object[]</p>
3989 *
3990 * <pre>
3991 * ArrayUtils.add(null, null) = [null]
3992 * ArrayUtils.add(null, "a") = ["a"]
3993 * ArrayUtils.add(["a"], null) = ["a", null]
3994 * ArrayUtils.add(["a"], "b") = ["a", "b"]
3995 * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
3996 * </pre>
3997 *
3998 * @param <T> the component type of the array
3999 * @param array the array to "add" the element to, may be {@code null}
4000 * @param element the object to add, may be {@code null}
4001 * @return A new array containing the existing elements plus the new element
4002 * The returned array type will be that of the input array (unless null),
4003 * in which case it will have the same type as the element.
4004 * If both are null, an IllegalArgumentException is thrown
4005 * @since 2.1
4006 * @throws IllegalArgumentException if both arguments are null
4007 */
4008 public static <T> T[] add(final T[] array, final T element) {
4009 Class<?> type;
4010 if (array != null){
4011 type = array.getClass().getComponentType();
4012 } else if (element != null) {
4013 type = element.getClass();
4014 } else {
4015 throw new IllegalArgumentException("Arguments cannot both be null");
4016 }
4017 @SuppressWarnings("unchecked") // type must be T
4018 final
4019 T[] newArray = (T[]) copyArrayGrow1(array, type);
4020 newArray[newArray.length - 1] = element;
4021 return newArray;
4022 }
4023
4024 /**
4025 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4026 *
4027 * <p>The new array contains the same elements of the input
4028 * array plus the given element in the last position. The component type of
4029 * the new array is the same as that of the input array.</p>
4030 *
4031 * <p>If the input array is {@code null}, a new one element array is returned
4032 * whose component type is the same as the element.</p>
4033 *
4034 * <pre>
4035 * ArrayUtils.add(null, true) = [true]
4036 * ArrayUtils.add([true], false) = [true, false]
4037 * ArrayUtils.add([true, false], true) = [true, false, true]
4038 * </pre>
4039 *
4040 * @param array the array to copy and add the element to, may be {@code null}
4041 * @param element the object to add at the last index of the new array
4042 * @return A new array containing the existing elements plus the new element
4043 * @since 2.1
4044 */
4045 public static boolean[] add(final boolean[] array, final boolean element) {
4046 final boolean[] newArray = (boolean[])copyArrayGrow1(array, Boolean.TYPE);
4047 newArray[newArray.length - 1] = element;
4048 return newArray;
4049 }
4050
4051 /**
4052 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4053 *
4054 * <p>The new array contains the same elements of the input
4055 * array plus the given element in the last position. The component type of
4056 * the new array is the same as that of the input array.</p>
4057 *
4058 * <p>If the input array is {@code null}, a new one element array is returned
4059 * whose component type is the same as the element.</p>
4060 *
4061 * <pre>
4062 * ArrayUtils.add(null, 0) = [0]
4063 * ArrayUtils.add([1], 0) = [1, 0]
4064 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4065 * </pre>
4066 *
4067 * @param array the array to copy and add the element to, may be {@code null}
4068 * @param element the object to add at the last index of the new array
4069 * @return A new array containing the existing elements plus the new element
4070 * @since 2.1
4071 */
4072 public static byte[] add(final byte[] array, final byte element) {
4073 final byte[] newArray = (byte[])copyArrayGrow1(array, Byte.TYPE);
4074 newArray[newArray.length - 1] = element;
4075 return newArray;
4076 }
4077
4078 /**
4079 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4080 *
4081 * <p>The new array contains the same elements of the input
4082 * array plus the given element in the last position. The component type of
4083 * the new array is the same as that of the input array.</p>
4084 *
4085 * <p>If the input array is {@code null}, a new one element array is returned
4086 * whose component type is the same as the element.</p>
4087 *
4088 * <pre>
4089 * ArrayUtils.add(null, '0') = ['0']
4090 * ArrayUtils.add(['1'], '0') = ['1', '0']
4091 * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
4092 * </pre>
4093 *
4094 * @param array the array to copy and add the element to, may be {@code null}
4095 * @param element the object to add at the last index of the new array
4096 * @return A new array containing the existing elements plus the new element
4097 * @since 2.1
4098 */
4099 public static char[] add(final char[] array, final char element) {
4100 final char[] newArray = (char[])copyArrayGrow1(array, Character.TYPE);
4101 newArray[newArray.length - 1] = element;
4102 return newArray;
4103 }
4104
4105 /**
4106 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4107 *
4108 * <p>The new array contains the same elements of the input
4109 * array plus the given element in the last position. The component type of
4110 * the new array is the same as that of the input array.</p>
4111 *
4112 * <p>If the input array is {@code null}, a new one element array is returned
4113 * whose component type is the same as the element.</p>
4114 *
4115 * <pre>
4116 * ArrayUtils.add(null, 0) = [0]
4117 * ArrayUtils.add([1], 0) = [1, 0]
4118 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4119 * </pre>
4120 *
4121 * @param array the array to copy and add the element to, may be {@code null}
4122 * @param element the object to add at the last index of the new array
4123 * @return A new array containing the existing elements plus the new element
4124 * @since 2.1
4125 */
4126 public static double[] add(final double[] array, final double element) {
4127 final double[] newArray = (double[])copyArrayGrow1(array, Double.TYPE);
4128 newArray[newArray.length - 1] = element;
4129 return newArray;
4130 }
4131
4132 /**
4133 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4134 *
4135 * <p>The new array contains the same elements of the input
4136 * array plus the given element in the last position. The component type of
4137 * the new array is the same as that of the input array.</p>
4138 *
4139 * <p>If the input array is {@code null}, a new one element array is returned
4140 * whose component type is the same as the element.</p>
4141 *
4142 * <pre>
4143 * ArrayUtils.add(null, 0) = [0]
4144 * ArrayUtils.add([1], 0) = [1, 0]
4145 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4146 * </pre>
4147 *
4148 * @param array the array to copy and add the element to, may be {@code null}
4149 * @param element the object to add at the last index of the new array
4150 * @return A new array containing the existing elements plus the new element
4151 * @since 2.1
4152 */
4153 public static float[] add(final float[] array, final float element) {
4154 final float[] newArray = (float[])copyArrayGrow1(array, Float.TYPE);
4155 newArray[newArray.length - 1] = element;
4156 return newArray;
4157 }
4158
4159 /**
4160 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4161 *
4162 * <p>The new array contains the same elements of the input
4163 * array plus the given element in the last position. The component type of
4164 * the new array is the same as that of the input array.</p>
4165 *
4166 * <p>If the input array is {@code null}, a new one element array is returned
4167 * whose component type is the same as the element.</p>
4168 *
4169 * <pre>
4170 * ArrayUtils.add(null, 0) = [0]
4171 * ArrayUtils.add([1], 0) = [1, 0]
4172 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4173 * </pre>
4174 *
4175 * @param array the array to copy and add the element to, may be {@code null}
4176 * @param element the object to add at the last index of the new array
4177 * @return A new array containing the existing elements plus the new element
4178 * @since 2.1
4179 */
4180 public static int[] add(final int[] array, final int element) {
4181 final int[] newArray = (int[])copyArrayGrow1(array, Integer.TYPE);
4182 newArray[newArray.length - 1] = element;
4183 return newArray;
4184 }
4185
4186 /**
4187 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4188 *
4189 * <p>The new array contains the same elements of the input
4190 * array plus the given element in the last position. The component type of
4191 * the new array is the same as that of the input array.</p>
4192 *
4193 * <p>If the input array is {@code null}, a new one element array is returned
4194 * whose component type is the same as the element.</p>
4195 *
4196 * <pre>
4197 * ArrayUtils.add(null, 0) = [0]
4198 * ArrayUtils.add([1], 0) = [1, 0]
4199 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4200 * </pre>
4201 *
4202 * @param array the array to copy and add the element to, may be {@code null}
4203 * @param element the object to add at the last index of the new array
4204 * @return A new array containing the existing elements plus the new element
4205 * @since 2.1
4206 */
4207 public static long[] add(final long[] array, final long element) {
4208 final long[] newArray = (long[])copyArrayGrow1(array, Long.TYPE);
4209 newArray[newArray.length - 1] = element;
4210 return newArray;
4211 }
4212
4213 /**
4214 * <p>Copies the given array and adds the given element at the end of the new array.</p>
4215 *
4216 * <p>The new array contains the same elements of the input
4217 * array plus the given element in the last position. The component type of
4218 * the new array is the same as that of the input array.</p>
4219 *
4220 * <p>If the input array is {@code null}, a new one element array is returned
4221 * whose component type is the same as the element.</p>
4222 *
4223 * <pre>
4224 * ArrayUtils.add(null, 0) = [0]
4225 * ArrayUtils.add([1], 0) = [1, 0]
4226 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
4227 * </pre>
4228 *
4229 * @param array the array to copy and add the element to, may be {@code null}
4230 * @param element the object to add at the last index of the new array
4231 * @return A new array containing the existing elements plus the new element
4232 * @since 2.1
4233 */
4234 public static short[] add(final short[] array, final short element) {
4235 final short[] newArray = (short[])copyArrayGrow1(array, Short.TYPE);
4236 newArray[newArray.length - 1] = element;
4237 return newArray;
4238 }
4239
4240 /**
4241 * Returns a copy of the given array of size 1 greater than the argument.
4242 * The last value of the array is left to the default value.
4243 *
4244 * @param array The array to copy, must not be {@code null}.
4245 * @param newArrayComponentType If {@code array} is {@code null}, create a
4246 * size 1 array of this type.
4247 * @return A new copy of the array of size 1 greater than the input.
4248 */
4249 private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
4250 if (array != null) {
4251 final int arrayLength = Array.getLength(array);
4252 final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
4253 System.arraycopy(array, 0, newArray, 0, arrayLength);
4254 return newArray;
4255 }
4256 return Array.newInstance(newArrayComponentType, 1);
4257 }
4258
4259 /**
4260 * <p>Inserts the specified element at the specified position in the array.
4261 * Shifts the element currently at that position (if any) and any subsequent
4262 * elements to the right (adds one to their indices).</p>
4263 *
4264 * <p>This method returns a new array with the same elements of the input
4265 * array plus the given element on the specified position. The component
4266 * type of the returned array is always the same as that of the input
4267 * array.</p>
4268 *
4269 * <p>If the input array is {@code null}, a new one element array is returned
4270 * whose component type is the same as the element.</p>
4271 *
4272 * <pre>
4273 * ArrayUtils.add(null, 0, null) = [null]
4274 * ArrayUtils.add(null, 0, "a") = ["a"]
4275 * ArrayUtils.add(["a"], 1, null) = ["a", null]
4276 * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
4277 * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
4278 * </pre>
4279 *
4280 * @param <T> the component type of the array
4281 * @param array the array to add the element to, may be {@code null}
4282 * @param index the position of the new object
4283 * @param element the object to add
4284 * @return A new array containing the existing elements and the new element
4285 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
4286 * @throws IllegalArgumentException if both array and element are null
4287 */
4288 public static <T> T[] add(final T[] array, final int index, final T element) {
4289 Class<?> clss = null;
4290 if (array != null) {
4291 clss = array.getClass().getComponentType();
4292 } else if (element != null) {
4293 clss = element.getClass();
4294 } else {
4295 throw new IllegalArgumentException("Array and element cannot both be null");
4296 }
4297 @SuppressWarnings("unchecked") // the add method creates an array of type clss, which is type T
4298 final T[] newArray = (T[]) add(array, index, element, clss);
4299 return newArray;
4300 }
4301
4302 /**
4303 * <p>Inserts the specified element at the specified position in the array.
4304 * Shifts the element currently at that position (if any) and any subsequent
4305 * elements to the right (adds one to their indices).</p>
4306 *
4307 * <p>This method returns a new array with the same elements of the input
4308 * array plus the given element on the specified position. The component
4309 * type of the returned array is always the same as that of the input
4310 * array.</p>
4311 *
4312 * <p>If the input array is {@code null}, a new one element array is returned
4313 * whose component type is the same as the element.</p>
4314 *
4315 * <pre>
4316 * ArrayUtils.add(null, 0, true) = [true]
4317 * ArrayUtils.add([true], 0, false) = [false, true]
4318 * ArrayUtils.add([false], 1, true) = [false, true]
4319 * ArrayUtils.add([true, false], 1, true) = [true, true, false]
4320 * </pre>
4321 *
4322 * @param array the array to add the element to, may be {@code null}
4323 * @param index the position of the new object
4324 * @param element the object to add
4325 * @return A new array containing the existing elements and the new element
4326 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
4327 */
4328 public static boolean[] add(final boolean[] array, final int index, final boolean element) {
4329 return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
4330 }
4331
4332 /**
4333 * <p>Inserts the specified element at the specified position in the array.
4334 * Shifts the element currently at that position (if any) and any subsequent
4335 * elements to the right (adds one to their indices).</p>
4336 *
4337 * <p>This method returns a new array with the same elements of the input
4338 * array plus the given element on the specified position. The component
4339 * type of the returned array is always the same as that of the input
4340 * array.</p>
4341 *
4342 * <p>If the input array is {@code null}, a new one element array is returned
4343 * whose component type is the same as the element.</p>
4344 *
4345 * <pre>
4346 * ArrayUtils.add(null, 0, 'a') = ['a']
4347 * ArrayUtils.add(['a'], 0, 'b') = ['b', 'a']
4348 * ArrayUtils.add(['a', 'b'], 0, 'c') = ['c', 'a', 'b']
4349 * ArrayUtils.add(['a', 'b'], 1, 'k') = ['a', 'k', 'b']
4350 * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
4351 * </pre>
4352 *
4353 * @param array the array to add the element to, may be {@code null}
4354 * @param index the position of the new object
4355 * @param element the object to add
4356 * @return A new array containing the existing elements and the new element
4357 * @throws IndexOutOfBoundsException if the index is out of range
4358 * (index < 0 || index > array.length).
4359 */
4360 public static char[] add(final char[] array, final int index, final char element) {
4361 return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
4362 }
4363
4364 /**
4365 * <p>Inserts the specified element at the specified position in the array.
4366 * Shifts the element currently at that position (if any) and any subsequent
4367 * elements to the right (adds one to their indices).</p>
4368 *
4369 * <p>This method returns a new array with the same elements of the input
4370 * array plus the given element on the specified position. The component
4371 * type of the returned array is always the same as that of the input
4372 * array.</p>
4373 *
4374 * <p>If the input array is {@code null}, a new one element array is returned
4375 * whose component type is the same as the element.</p>
4376 *
4377 * <pre>
4378 * ArrayUtils.add([1], 0, 2) = [2, 1]
4379 * ArrayUtils.add([2, 6], 2, 3) = [2, 6, 3]
4380 * ArrayUtils.add([2, 6], 0, 1) = [1, 2, 6]
4381 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4382 * </pre>
4383 *
4384 * @param array the array to add the element to, may be {@code null}
4385 * @param index the position of the new object
4386 * @param element the object to add
4387 * @return A new array containing the existing elements and the new element
4388 * @throws IndexOutOfBoundsException if the index is out of range
4389 * (index < 0 || index > array.length).
4390 */
4391 public static byte[] add(final byte[] array, final int index, final byte element) {
4392 return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
4393 }
4394
4395 /**
4396 * <p>Inserts the specified element at the specified position in the array.
4397 * Shifts the element currently at that position (if any) and any subsequent
4398 * elements to the right (adds one to their indices).</p>
4399 *
4400 * <p>This method returns a new array with the same elements of the input
4401 * array plus the given element on the specified position. The component
4402 * type of the returned array is always the same as that of the input
4403 * array.</p>
4404 *
4405 * <p>If the input array is {@code null}, a new one element array is returned
4406 * whose component type is the same as the element.</p>
4407 *
4408 * <pre>
4409 * ArrayUtils.add([1], 0, 2) = [2, 1]
4410 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
4411 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
4412 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4413 * </pre>
4414 *
4415 * @param array the array to add the element to, may be {@code null}
4416 * @param index the position of the new object
4417 * @param element the object to add
4418 * @return A new array containing the existing elements and the new element
4419 * @throws IndexOutOfBoundsException if the index is out of range
4420 * (index < 0 || index > array.length).
4421 */
4422 public static short[] add(final short[] array, final int index, final short element) {
4423 return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
4424 }
4425
4426 /**
4427 * <p>Inserts the specified element at the specified position in the array.
4428 * Shifts the element currently at that position (if any) and any subsequent
4429 * elements to the right (adds one to their indices).</p>
4430 *
4431 * <p>This method returns a new array with the same elements of the input
4432 * array plus the given element on the specified position. The component
4433 * type of the returned array is always the same as that of the input
4434 * array.</p>
4435 *
4436 * <p>If the input array is {@code null}, a new one element array is returned
4437 * whose component type is the same as the element.</p>
4438 *
4439 * <pre>
4440 * ArrayUtils.add([1], 0, 2) = [2, 1]
4441 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
4442 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
4443 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4444 * </pre>
4445 *
4446 * @param array the array to add the element to, may be {@code null}
4447 * @param index the position of the new object
4448 * @param element the object to add
4449 * @return A new array containing the existing elements and the new element
4450 * @throws IndexOutOfBoundsException if the index is out of range
4451 * (index < 0 || index > array.length).
4452 */
4453 public static int[] add(final int[] array, final int index, final int element) {
4454 return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
4455 }
4456
4457 /**
4458 * <p>Inserts the specified element at the specified position in the array.
4459 * Shifts the element currently at that position (if any) and any subsequent
4460 * elements to the right (adds one to their indices).</p>
4461 *
4462 * <p>This method returns a new array with the same elements of the input
4463 * array plus the given element on the specified position. The component
4464 * type of the returned array is always the same as that of the input
4465 * array.</p>
4466 *
4467 * <p>If the input array is {@code null}, a new one element array is returned
4468 * whose component type is the same as the element.</p>
4469 *
4470 * <pre>
4471 * ArrayUtils.add([1L], 0, 2L) = [2L, 1L]
4472 * ArrayUtils.add([2L, 6L], 2, 10L) = [2L, 6L, 10L]
4473 * ArrayUtils.add([2L, 6L], 0, -4L) = [-4L, 2L, 6L]
4474 * ArrayUtils.add([2L, 6L, 3L], 2, 1L) = [2L, 6L, 1L, 3L]
4475 * </pre>
4476 *
4477 * @param array the array to add the element to, may be {@code null}
4478 * @param index the position of the new object
4479 * @param element the object to add
4480 * @return A new array containing the existing elements and the new element
4481 * @throws IndexOutOfBoundsException if the index is out of range
4482 * (index < 0 || index > array.length).
4483 */
4484 public static long[] add(final long[] array, final int index, final long element) {
4485 return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
4486 }
4487
4488 /**
4489 * <p>Inserts the specified element at the specified position in the array.
4490 * Shifts the element currently at that position (if any) and any subsequent
4491 * elements to the right (adds one to their indices).</p>
4492 *
4493 * <p>This method returns a new array with the same elements of the input
4494 * array plus the given element on the specified position. The component
4495 * type of the returned array is always the same as that of the input
4496 * array.</p>
4497 *
4498 * <p>If the input array is {@code null}, a new one element array is returned
4499 * whose component type is the same as the element.</p>
4500 *
4501 * <pre>
4502 * ArrayUtils.add([1.1f], 0, 2.2f) = [2.2f, 1.1f]
4503 * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f) = [2.3f, 6.4f, 10.5f]
4504 * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f) = [-4.8f, 2.6f, 6.7f]
4505 * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f) = [2.9f, 6.0f, 1.0f, 0.3f]
4506 * </pre>
4507 *
4508 * @param array the array to add the element to, may be {@code null}
4509 * @param index the position of the new object
4510 * @param element the object to add
4511 * @return A new array containing the existing elements and the new element
4512 * @throws IndexOutOfBoundsException if the index is out of range
4513 * (index < 0 || index > array.length).
4514 */
4515 public static float[] add(final float[] array, final int index, final float element) {
4516 return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
4517 }
4518
4519 /**
4520 * <p>Inserts the specified element at the specified position in the array.
4521 * Shifts the element currently at that position (if any) and any subsequent
4522 * elements to the right (adds one to their indices).</p>
4523 *
4524 * <p>This method returns a new array with the same elements of the input
4525 * array plus the given element on the specified position. The component
4526 * type of the returned array is always the same as that of the input
4527 * array.</p>
4528 *
4529 * <p>If the input array is {@code null}, a new one element array is returned
4530 * whose component type is the same as the element.</p>
4531 *
4532 * <pre>
4533 * ArrayUtils.add([1.1], 0, 2.2) = [2.2, 1.1]
4534 * ArrayUtils.add([2.3, 6.4], 2, 10.5) = [2.3, 6.4, 10.5]
4535 * ArrayUtils.add([2.6, 6.7], 0, -4.8) = [-4.8, 2.6, 6.7]
4536 * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0) = [2.9, 6.0, 1.0, 0.3]
4537 * </pre>
4538 *
4539 * @param array the array to add the element to, may be {@code null}
4540 * @param index the position of the new object
4541 * @param element the object to add
4542 * @return A new array containing the existing elements and the new element
4543 * @throws IndexOutOfBoundsException if the index is out of range
4544 * (index < 0 || index > array.length).
4545 */
4546 public static double[] add(final double[] array, final int index, final double element) {
4547 return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
4548 }
4549
4550 /**
4551 * Underlying implementation of add(array, index, element) methods.
4552 * The last parameter is the class, which may not equal element.getClass
4553 * for primitives.
4554 *
4555 * @param array the array to add the element to, may be {@code null}
4556 * @param index the position of the new object
4557 * @param element the object to add
4558 * @param clss the type of the element being added
4559 * @return A new array containing the existing elements and the new element
4560 */
4561 private static Object add(final Object array, final int index, final Object element, final Class<?> clss) {
4562 if (array == null) {
4563 if (index != 0) {
4564 throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
4565 }
4566 final Object joinedArray = Array.newInstance(clss, 1);
4567 Array.set(joinedArray, 0, element);
4568 return joinedArray;
4569 }
4570 final int length = Array.getLength(array);
4571 if (index > length || index < 0) {
4572 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4573 }
4574 final Object result = Array.newInstance(clss, length + 1);
4575 System.arraycopy(array, 0, result, 0, index);
4576 Array.set(result, index, element);
4577 if (index < length) {
4578 System.arraycopy(array, index, result, index + 1, length - index);
4579 }
4580 return result;
4581 }
4582
4583 /**
4584 * <p>Removes the element at the specified position from the specified array.
4585 * All subsequent elements are shifted to the left (subtracts one from
4586 * their indices).</p>
4587 *
4588 * <p>This method returns a new array with the same elements of the input
4589 * array except the element on the specified position. The component
4590 * type of the returned array is always the same as that of the input
4591 * array.</p>
4592 *
4593 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4594 * will be thrown, because in that case no valid index can be specified.</p>
4595 *
4596 * <pre>
4597 * ArrayUtils.remove(["a"], 0) = []
4598 * ArrayUtils.remove(["a", "b"], 0) = ["b"]
4599 * ArrayUtils.remove(["a", "b"], 1) = ["a"]
4600 * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
4601 * </pre>
4602 *
4603 * @param <T> the component type of the array
4604 * @param array the array to remove the element from, may not be {@code null}
4605 * @param index the position of the element to be removed
4606 * @return A new array containing the existing elements except the element
4607 * at the specified position.
4608 * @throws IndexOutOfBoundsException if the index is out of range
4609 * (index < 0 || index >= array.length), or if the array is {@code null}.
4610 * @since 2.1
4611 */
4612 @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
4613 public static <T> T[] remove(final T[] array, final int index) {
4614 return (T[]) remove((Object) array, index);
4615 }
4616
4617 /**
4618 * <p>Removes the first occurrence of the specified element from the
4619 * specified array. All subsequent elements are shifted to the left
4620 * (subtracts one from their indices). If the array doesn't contains
4621 * such an element, no elements are removed from the array.</p>
4622 *
4623 * <p>This method returns a new array with the same elements of the input
4624 * array except the first occurrence of the specified element. The component
4625 * type of the returned array is always the same as that of the input
4626 * array.</p>
4627 *
4628 * <pre>
4629 * ArrayUtils.removeElement(null, "a") = null
4630 * ArrayUtils.removeElement([], "a") = []
4631 * ArrayUtils.removeElement(["a"], "b") = ["a"]
4632 * ArrayUtils.removeElement(["a", "b"], "a") = ["b"]
4633 * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
4634 * </pre>
4635 *
4636 * @param <T> the component type of the array
4637 * @param array the array to remove the element from, may be {@code null}
4638 * @param element the element to be removed
4639 * @return A new array containing the existing elements except the first
4640 * occurrence of the specified element.
4641 * @since 2.1
4642 */
4643 public static <T> T[] removeElement(final T[] array, final Object element) {
4644 final int index = indexOf(array, element);
4645 if (index == INDEX_NOT_FOUND) {
4646 return clone(array);
4647 }
4648 return remove(array, index);
4649 }
4650
4651 /**
4652 * <p>Removes the element at the specified position from the specified array.
4653 * All subsequent elements are shifted to the left (subtracts one from
4654 * their indices).</p>
4655 *
4656 * <p>This method returns a new array with the same elements of the input
4657 * array except the element on the specified position. The component
4658 * type of the returned array is always the same as that of the input
4659 * array.</p>
4660 *
4661 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4662 * will be thrown, because in that case no valid index can be specified.</p>
4663 *
4664 * <pre>
4665 * ArrayUtils.remove([true], 0) = []
4666 * ArrayUtils.remove([true, false], 0) = [false]
4667 * ArrayUtils.remove([true, false], 1) = [true]
4668 * ArrayUtils.remove([true, true, false], 1) = [true, false]
4669 * </pre>
4670 *
4671 * @param array the array to remove the element from, may not be {@code null}
4672 * @param index the position of the element to be removed
4673 * @return A new array containing the existing elements except the element
4674 * at the specified position.
4675 * @throws IndexOutOfBoundsException if the index is out of range
4676 * (index < 0 || index >= array.length), or if the array is {@code null}.
4677 * @since 2.1
4678 */
4679 public static boolean[] remove(final boolean[] array, final int index) {
4680 return (boolean[]) remove((Object) array, index);
4681 }
4682
4683 /**
4684 * <p>Removes the first occurrence of the specified element from the
4685 * specified array. All subsequent elements are shifted to the left
4686 * (subtracts one from their indices). If the array doesn't contains
4687 * such an element, no elements are removed from the array.</p>
4688 *
4689 * <p>This method returns a new array with the same elements of the input
4690 * array except the first occurrence of the specified element. The component
4691 * type of the returned array is always the same as that of the input
4692 * array.</p>
4693 *
4694 * <pre>
4695 * ArrayUtils.removeElement(null, true) = null
4696 * ArrayUtils.removeElement([], true) = []
4697 * ArrayUtils.removeElement([true], false) = [true]
4698 * ArrayUtils.removeElement([true, false], false) = [true]
4699 * ArrayUtils.removeElement([true, false, true], true) = [false, true]
4700 * </pre>
4701 *
4702 * @param array the array to remove the element from, may be {@code null}
4703 * @param element the element to be removed
4704 * @return A new array containing the existing elements except the first
4705 * occurrence of the specified element.
4706 * @since 2.1
4707 */
4708 public static boolean[] removeElement(final boolean[] array, final boolean element) {
4709 final int index = indexOf(array, element);
4710 if (index == INDEX_NOT_FOUND) {
4711 return clone(array);
4712 }
4713 return remove(array, index);
4714 }
4715
4716 /**
4717 * <p>Removes the element at the specified position from the specified array.
4718 * All subsequent elements are shifted to the left (subtracts one from
4719 * their indices).</p>
4720 *
4721 * <p>This method returns a new array with the same elements of the input
4722 * array except the element on the specified position. The component
4723 * type of the returned array is always the same as that of the input
4724 * array.</p>
4725 *
4726 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4727 * will be thrown, because in that case no valid index can be specified.</p>
4728 *
4729 * <pre>
4730 * ArrayUtils.remove([1], 0) = []
4731 * ArrayUtils.remove([1, 0], 0) = [0]
4732 * ArrayUtils.remove([1, 0], 1) = [1]
4733 * ArrayUtils.remove([1, 0, 1], 1) = [1, 1]
4734 * </pre>
4735 *
4736 * @param array the array to remove the element from, may not be {@code null}
4737 * @param index the position of the element to be removed
4738 * @return A new array containing the existing elements except the element
4739 * at the specified position.
4740 * @throws IndexOutOfBoundsException if the index is out of range
4741 * (index < 0 || index >= array.length), or if the array is {@code null}.
4742 * @since 2.1
4743 */
4744 public static byte[] remove(final byte[] array, final int index) {
4745 return (byte[]) remove((Object) array, index);
4746 }
4747
4748 /**
4749 * <p>Removes the first occurrence of the specified element from the
4750 * specified array. All subsequent elements are shifted to the left
4751 * (subtracts one from their indices). If the array doesn't contains
4752 * such an element, no elements are removed from the array.</p>
4753 *
4754 * <p>This method returns a new array with the same elements of the input
4755 * array except the first occurrence of the specified element. The component
4756 * type of the returned array is always the same as that of the input
4757 * array.</p>
4758 *
4759 * <pre>
4760 * ArrayUtils.removeElement(null, 1) = null
4761 * ArrayUtils.removeElement([], 1) = []
4762 * ArrayUtils.removeElement([1], 0) = [1]
4763 * ArrayUtils.removeElement([1, 0], 0) = [1]
4764 * ArrayUtils.removeElement([1, 0, 1], 1) = [0, 1]
4765 * </pre>
4766 *
4767 * @param array the array to remove the element from, may be {@code null}
4768 * @param element the element to be removed
4769 * @return A new array containing the existing elements except the first
4770 * occurrence of the specified element.
4771 * @since 2.1
4772 */
4773 public static byte[] removeElement(final byte[] array, final byte element) {
4774 final int index = indexOf(array, element);
4775 if (index == INDEX_NOT_FOUND) {
4776 return clone(array);
4777 }
4778 return remove(array, index);
4779 }
4780
4781 /**
4782 * <p>Removes the element at the specified position from the specified array.
4783 * All subsequent elements are shifted to the left (subtracts one from
4784 * their indices).</p>
4785 *
4786 * <p>This method returns a new array with the same elements of the input
4787 * array except the element on the specified position. The component
4788 * type of the returned array is always the same as that of the input
4789 * array.</p>
4790 *
4791 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4792 * will be thrown, because in that case no valid index can be specified.</p>
4793 *
4794 * <pre>
4795 * ArrayUtils.remove(['a'], 0) = []
4796 * ArrayUtils.remove(['a', 'b'], 0) = ['b']
4797 * ArrayUtils.remove(['a', 'b'], 1) = ['a']
4798 * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
4799 * </pre>
4800 *
4801 * @param array the array to remove the element from, may not be {@code null}
4802 * @param index the position of the element to be removed
4803 * @return A new array containing the existing elements except the element
4804 * at the specified position.
4805 * @throws IndexOutOfBoundsException if the index is out of range
4806 * (index < 0 || index >= array.length), or if the array is {@code null}.
4807 * @since 2.1
4808 */
4809 public static char[] remove(final char[] array, final int index) {
4810 return (char[]) remove((Object) array, index);
4811 }
4812
4813 /**
4814 * <p>Removes the first occurrence of the specified element from the
4815 * specified array. All subsequent elements are shifted to the left
4816 * (subtracts one from their indices). If the array doesn't contains
4817 * such an element, no elements are removed from the array.</p>
4818 *
4819 * <p>This method returns a new array with the same elements of the input
4820 * array except the first occurrence of the specified element. The component
4821 * type of the returned array is always the same as that of the input
4822 * array.</p>
4823 *
4824 * <pre>
4825 * ArrayUtils.removeElement(null, 'a') = null
4826 * ArrayUtils.removeElement([], 'a') = []
4827 * ArrayUtils.removeElement(['a'], 'b') = ['a']
4828 * ArrayUtils.removeElement(['a', 'b'], 'a') = ['b']
4829 * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
4830 * </pre>
4831 *
4832 * @param array the array to remove the element from, may be {@code null}
4833 * @param element the element to be removed
4834 * @return A new array containing the existing elements except the first
4835 * occurrence of the specified element.
4836 * @since 2.1
4837 */
4838 public static char[] removeElement(final char[] array, final char element) {
4839 final int index = indexOf(array, element);
4840 if (index == INDEX_NOT_FOUND) {
4841 return clone(array);
4842 }
4843 return remove(array, index);
4844 }
4845
4846 /**
4847 * <p>Removes the element at the specified position from the specified array.
4848 * All subsequent elements are shifted to the left (subtracts one from
4849 * their indices).</p>
4850 *
4851 * <p>This method returns a new array with the same elements of the input
4852 * array except the element on the specified position. The component
4853 * type of the returned array is always the same as that of the input
4854 * array.</p>
4855 *
4856 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4857 * will be thrown, because in that case no valid index can be specified.</p>
4858 *
4859 * <pre>
4860 * ArrayUtils.remove([1.1], 0) = []
4861 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4862 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4863 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4864 * </pre>
4865 *
4866 * @param array the array to remove the element from, may not be {@code null}
4867 * @param index the position of the element to be removed
4868 * @return A new array containing the existing elements except the element
4869 * at the specified position.
4870 * @throws IndexOutOfBoundsException if the index is out of range
4871 * (index < 0 || index >= array.length), or if the array is {@code null}.
4872 * @since 2.1
4873 */
4874 public static double[] remove(final double[] array, final int index) {
4875 return (double[]) remove((Object) array, index);
4876 }
4877
4878 /**
4879 * <p>Removes the first occurrence of the specified element from the
4880 * specified array. All subsequent elements are shifted to the left
4881 * (subtracts one from their indices). If the array doesn't contains
4882 * such an element, no elements are removed from the array.</p>
4883 *
4884 * <p>This method returns a new array with the same elements of the input
4885 * array except the first occurrence of the specified element. The component
4886 * type of the returned array is always the same as that of the input
4887 * array.</p>
4888 *
4889 * <pre>
4890 * ArrayUtils.removeElement(null, 1.1) = null
4891 * ArrayUtils.removeElement([], 1.1) = []
4892 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
4893 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
4894 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4895 * </pre>
4896 *
4897 * @param array the array to remove the element from, may be {@code null}
4898 * @param element the element to be removed
4899 * @return A new array containing the existing elements except the first
4900 * occurrence of the specified element.
4901 * @since 2.1
4902 */
4903 public static double[] removeElement(final double[] array, final double element) {
4904 final int index = indexOf(array, element);
4905 if (index == INDEX_NOT_FOUND) {
4906 return clone(array);
4907 }
4908 return remove(array, index);
4909 }
4910
4911 /**
4912 * <p>Removes the element at the specified position from the specified array.
4913 * All subsequent elements are shifted to the left (subtracts one from
4914 * their indices).</p>
4915 *
4916 * <p>This method returns a new array with the same elements of the input
4917 * array except the element on the specified position. The component
4918 * type of the returned array is always the same as that of the input
4919 * array.</p>
4920 *
4921 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4922 * will be thrown, because in that case no valid index can be specified.</p>
4923 *
4924 * <pre>
4925 * ArrayUtils.remove([1.1], 0) = []
4926 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4927 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4928 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4929 * </pre>
4930 *
4931 * @param array the array to remove the element from, may not be {@code null}
4932 * @param index the position of the element to be removed
4933 * @return A new array containing the existing elements except the element
4934 * at the specified position.
4935 * @throws IndexOutOfBoundsException if the index is out of range
4936 * (index < 0 || index >= array.length), or if the array is {@code null}.
4937 * @since 2.1
4938 */
4939 public static float[] remove(final float[] array, final int index) {
4940 return (float[]) remove((Object) array, index);
4941 }
4942
4943 /**
4944 * <p>Removes the first occurrence of the specified element from the
4945 * specified array. All subsequent elements are shifted to the left
4946 * (subtracts one from their indices). If the array doesn't contains
4947 * such an element, no elements are removed from the array.</p>
4948 *
4949 * <p>This method returns a new array with the same elements of the input
4950 * array except the first occurrence of the specified element. The component
4951 * type of the returned array is always the same as that of the input
4952 * array.</p>
4953 *
4954 * <pre>
4955 * ArrayUtils.removeElement(null, 1.1) = null
4956 * ArrayUtils.removeElement([], 1.1) = []
4957 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
4958 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
4959 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4960 * </pre>
4961 *
4962 * @param array the array to remove the element from, may be {@code null}
4963 * @param element the element to be removed
4964 * @return A new array containing the existing elements except the first
4965 * occurrence of the specified element.
4966 * @since 2.1
4967 */
4968 public static float[] removeElement(final float[] array, final float element) {
4969 final int index = indexOf(array, element);
4970 if (index == INDEX_NOT_FOUND) {
4971 return clone(array);
4972 }
4973 return remove(array, index);
4974 }
4975
4976 /**
4977 * <p>Removes the element at the specified position from the specified array.
4978 * All subsequent elements are shifted to the left (subtracts one from
4979 * their indices).</p>
4980 *
4981 * <p>This method returns a new array with the same elements of the input
4982 * array except the element on the specified position. The component
4983 * type of the returned array is always the same as that of the input
4984 * array.</p>
4985 *
4986 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4987 * will be thrown, because in that case no valid index can be specified.</p>
4988 *
4989 * <pre>
4990 * ArrayUtils.remove([1], 0) = []
4991 * ArrayUtils.remove([2, 6], 0) = [6]
4992 * ArrayUtils.remove([2, 6], 1) = [2]
4993 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4994 * </pre>
4995 *
4996 * @param array the array to remove the element from, may not be {@code null}
4997 * @param index the position of the element to be removed
4998 * @return A new array containing the existing elements except the element
4999 * at the specified position.
5000 * @throws IndexOutOfBoundsException if the index is out of range
5001 * (index < 0 || index >= array.length), or if the array is {@code null}.
5002 * @since 2.1
5003 */
5004 public static int[] remove(final int[] array, final int index) {
5005 return (int[]) remove((Object) array, index);
5006 }
5007
5008 /**
5009 * <p>Removes the first occurrence of the specified element from the
5010 * specified array. All subsequent elements are shifted to the left
5011 * (subtracts one from their indices). If the array doesn't contains
5012 * such an element, no elements are removed from the array.</p>
5013 *
5014 * <p>This method returns a new array with the same elements of the input
5015 * array except the first occurrence of the specified element. The component
5016 * type of the returned array is always the same as that of the input
5017 * array.</p>
5018 *
5019 * <pre>
5020 * ArrayUtils.removeElement(null, 1) = null
5021 * ArrayUtils.removeElement([], 1) = []
5022 * ArrayUtils.removeElement([1], 2) = [1]
5023 * ArrayUtils.removeElement([1, 3], 1) = [3]
5024 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
5025 * </pre>
5026 *
5027 * @param array the array to remove the element from, may be {@code null}
5028 * @param element the element to be removed
5029 * @return A new array containing the existing elements except the first
5030 * occurrence of the specified element.
5031 * @since 2.1
5032 */
5033 public static int[] removeElement(final int[] array, final int element) {
5034 final int index = indexOf(array, element);
5035 if (index == INDEX_NOT_FOUND) {
5036 return clone(array);
5037 }
5038 return remove(array, index);
5039 }
5040
5041 /**
5042 * <p>Removes the element at the specified position from the specified array.
5043 * All subsequent elements are shifted to the left (subtracts one from
5044 * their indices).</p>
5045 *
5046 * <p>This method returns a new array with the same elements of the input
5047 * array except the element on the specified position. The component
5048 * type of the returned array is always the same as that of the input
5049 * array.</p>
5050 *
5051 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5052 * will be thrown, because in that case no valid index can be specified.</p>
5053 *
5054 * <pre>
5055 * ArrayUtils.remove([1], 0) = []
5056 * ArrayUtils.remove([2, 6], 0) = [6]
5057 * ArrayUtils.remove([2, 6], 1) = [2]
5058 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5059 * </pre>
5060 *
5061 * @param array the array to remove the element from, may not be {@code null}
5062 * @param index the position of the element to be removed
5063 * @return A new array containing the existing elements except the element
5064 * at the specified position.
5065 * @throws IndexOutOfBoundsException if the index is out of range
5066 * (index < 0 || index >= array.length), or if the array is {@code null}.
5067 * @since 2.1
5068 */
5069 public static long[] remove(final long[] array, final int index) {
5070 return (long[]) remove((Object) array, index);
5071 }
5072
5073 /**
5074 * <p>Removes the first occurrence of the specified element from the
5075 * specified array. All subsequent elements are shifted to the left
5076 * (subtracts one from their indices). If the array doesn't contains
5077 * such an element, no elements are removed from the array.</p>
5078 *
5079 * <p>This method returns a new array with the same elements of the input
5080 * array except the first occurrence of the specified element. The component
5081 * type of the returned array is always the same as that of the input
5082 * array.</p>
5083 *
5084 * <pre>
5085 * ArrayUtils.removeElement(null, 1) = null
5086 * ArrayUtils.removeElement([], 1) = []
5087 * ArrayUtils.removeElement([1], 2) = [1]
5088 * ArrayUtils.removeElement([1, 3], 1) = [3]
5089 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
5090 * </pre>
5091 *
5092 * @param array the array to remove the element from, may be {@code null}
5093 * @param element the element to be removed
5094 * @return A new array containing the existing elements except the first
5095 * occurrence of the specified element.
5096 * @since 2.1
5097 */
5098 public static long[] removeElement(final long[] array, final long element) {
5099 final int index = indexOf(array, element);
5100 if (index == INDEX_NOT_FOUND) {
5101 return clone(array);
5102 }
5103 return remove(array, index);
5104 }
5105
5106 /**
5107 * <p>Removes the element at the specified position from the specified array.
5108 * All subsequent elements are shifted to the left (subtracts one from
5109 * their indices).</p>
5110 *
5111 * <p>This method returns a new array with the same elements of the input
5112 * array except the element on the specified position. The component
5113 * type of the returned array is always the same as that of the input
5114 * array.</p>
5115 *
5116 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5117 * will be thrown, because in that case no valid index can be specified.</p>
5118 *
5119 * <pre>
5120 * ArrayUtils.remove([1], 0) = []
5121 * ArrayUtils.remove([2, 6], 0) = [6]
5122 * ArrayUtils.remove([2, 6], 1) = [2]
5123 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5124 * </pre>
5125 *
5126 * @param array the array to remove the element from, may not be {@code null}
5127 * @param index the position of the element to be removed
5128 * @return A new array containing the existing elements except the element
5129 * at the specified position.
5130 * @throws IndexOutOfBoundsException if the index is out of range
5131 * (index < 0 || index >= array.length), or if the array is {@code null}.
5132 * @since 2.1
5133 */
5134 public static short[] remove(final short[] array, final int index) {
5135 return (short[]) remove((Object) array, index);
5136 }
5137
5138 /**
5139 * <p>Removes the first occurrence of the specified element from the
5140 * specified array. All subsequent elements are shifted to the left
5141 * (subtracts one from their indices). If the array doesn't contains
5142 * such an element, no elements are removed from the array.</p>
5143 *
5144 * <p>This method returns a new array with the same elements of the input
5145 * array except the first occurrence of the specified element. The component
5146 * type of the returned array is always the same as that of the input
5147 * array.</p>
5148 *
5149 * <pre>
5150 * ArrayUtils.removeElement(null, 1) = null
5151 * ArrayUtils.removeElement([], 1) = []
5152 * ArrayUtils.removeElement([1], 2) = [1]
5153 * ArrayUtils.removeElement([1, 3], 1) = [3]
5154 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
5155 * </pre>
5156 *
5157 * @param array the array to remove the element from, may be {@code null}
5158 * @param element the element to be removed
5159 * @return A new array containing the existing elements except the first
5160 * occurrence of the specified element.
5161 * @since 2.1
5162 */
5163 public static short[] removeElement(final short[] array, final short element) {
5164 final int index = indexOf(array, element);
5165 if (index == INDEX_NOT_FOUND) {
5166 return clone(array);
5167 }
5168 return remove(array, index);
5169 }
5170
5171 /**
5172 * <p>Removes the element at the specified position from the specified array.
5173 * All subsequent elements are shifted to the left (subtracts one from
5174 * their indices).</p>
5175 *
5176 * <p>This method returns a new array with the same elements of the input
5177 * array except the element on the specified position. The component
5178 * type of the returned array is always the same as that of the input
5179 * array.</p>
5180 *
5181 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5182 * will be thrown, because in that case no valid index can be specified.</p>
5183 *
5184 * @param array the array to remove the element from, may not be {@code null}
5185 * @param index the position of the element to be removed
5186 * @return A new array containing the existing elements except the element
5187 * at the specified position.
5188 * @throws IndexOutOfBoundsException if the index is out of range
5189 * (index < 0 || index >= array.length), or if the array is {@code null}.
5190 * @since 2.1
5191 */
5192 private static Object remove(final Object array, final int index) {
5193 final int length = getLength(array);
5194 if (index < 0 || index >= length) {
5195 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
5196 }
5197
5198 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
5199 System.arraycopy(array, 0, result, 0, index);
5200 if (index < length - 1) {
5201 System.arraycopy(array, index + 1, result, index, length - index - 1);
5202 }
5203
5204 return result;
5205 }
5206
5207 /**
5208 * <p>Removes the elements at the specified positions from the specified array.
5209 * All remaining elements are shifted to the left.</p>
5210 *
5211 * <p>This method returns a new array with the same elements of the input
5212 * array except those at the specified positions. The component
5213 * type of the returned array is always the same as that of the input
5214 * array.</p>
5215 *
5216 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5217 * will be thrown, because in that case no valid index can be specified.</p>
5218 *
5219 * <pre>
5220 * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
5221 * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
5222 * </pre>
5223 *
5224 * @param <T> the component type of the array
5225 * @param array the array to remove the element from, may not be {@code null}
5226 * @param indices the positions of the elements to be removed
5227 * @return A new array containing the existing elements except those
5228 * at the specified positions.
5229 * @throws IndexOutOfBoundsException if any index is out of range
5230 * (index < 0 || index >= array.length), or if the array is {@code null}.
5231 * @since 3.0.1
5232 */
5233 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
5234 public static <T> T[] removeAll(final T[] array, final int... indices) {
5235 return (T[]) removeAll((Object) array, clone(indices));
5236 }
5237
5238 /**
5239 * <p>Removes occurrences of specified elements, in specified quantities,
5240 * from the specified array. All subsequent elements are shifted left.
5241 * For any element-to-be-removed specified in greater quantities than
5242 * contained in the original array, no change occurs beyond the
5243 * removal of the existing matching items.</p>
5244 *
5245 * <p>This method returns a new array with the same elements of the input
5246 * array except for the earliest-encountered occurrences of the specified
5247 * elements. The component type of the returned array is always the same
5248 * as that of the input array.</p>
5249 *
5250 * <pre>
5251 * ArrayUtils.removeElements(null, "a", "b") = null
5252 * ArrayUtils.removeElements([], "a", "b") = []
5253 * ArrayUtils.removeElements(["a"], "b", "c") = ["a"]
5254 * ArrayUtils.removeElements(["a", "b"], "a", "c") = ["b"]
5255 * ArrayUtils.removeElements(["a", "b", "a"], "a") = ["b", "a"]
5256 * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
5257 * </pre>
5258 *
5259 * @param <T> the component type of the array
5260 * @param array the array to remove the element from, may be {@code null}
5261 * @param values the elements to be removed
5262 * @return A new array containing the existing elements except the
5263 * earliest-encountered occurrences of the specified elements.
5264 * @since 3.0.1
5265 */
5266 public static <T> T[] removeElements(final T[] array, final T... values) {
5267 if (isEmpty(array) || isEmpty(values)) {
5268 return clone(array);
5269 }
5270 final HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(values.length);
5271 for (final T v : values) {
5272 final MutableInt count = occurrences.get(v);
5273 if (count == null) {
5274 occurrences.put(v, new MutableInt(1));
5275 } else {
5276 count.increment();
5277 }
5278 }
5279 final BitSet toRemove = new BitSet();
5280 for (final Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
5281 final T v = e.getKey();
5282 int found = 0;
5283 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5284 found = indexOf(array, v, found);
5285 if (found < 0) {
5286 break;
5287 }
5288 toRemove.set(found++);
5289 }
5290 }
5291 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
5292 final
5293 T[] result = (T[]) removeAll(array, toRemove);
5294 return result;
5295 }
5296
5297 /**
5298 * <p>Removes the elements at the specified positions from the specified array.
5299 * All remaining elements are shifted to the left.</p>
5300 *
5301 * <p>This method returns a new array with the same elements of the input
5302 * array except those at the specified positions. The component
5303 * type of the returned array is always the same as that of the input
5304 * array.</p>
5305 *
5306 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5307 * will be thrown, because in that case no valid index can be specified.</p>
5308 *
5309 * <pre>
5310 * ArrayUtils.removeAll([1], 0) = []
5311 * ArrayUtils.removeAll([2, 6], 0) = [6]
5312 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5313 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5314 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5315 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5316 * </pre>
5317 *
5318 * @param array the array to remove the element from, may not be {@code null}
5319 * @param indices the positions of the elements to be removed
5320 * @return A new array containing the existing elements except those
5321 * at the specified positions.
5322 * @throws IndexOutOfBoundsException if any index is out of range
5323 * (index < 0 || index >= array.length), or if the array is {@code null}.
5324 * @since 3.0.1
5325 */
5326 public static byte[] removeAll(final byte[] array, final int... indices) {
5327 return (byte[]) removeAll((Object) array, clone(indices));
5328 }
5329
5330 /**
5331 * <p>Removes occurrences of specified elements, in specified quantities,
5332 * from the specified array. All subsequent elements are shifted left.
5333 * For any element-to-be-removed specified in greater quantities than
5334 * contained in the original array, no change occurs beyond the
5335 * removal of the existing matching items.</p>
5336 *
5337 * <p>This method returns a new array with the same elements of the input
5338 * array except for the earliest-encountered occurrences of the specified
5339 * elements. The component type of the returned array is always the same
5340 * as that of the input array.</p>
5341 *
5342 * <pre>
5343 * ArrayUtils.removeElements(null, 1, 2) = null
5344 * ArrayUtils.removeElements([], 1, 2) = []
5345 * ArrayUtils.removeElements([1], 2, 3) = [1]
5346 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5347 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5348 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5349 * </pre>
5350 *
5351 * @param array the array to remove the element from, may be {@code null}
5352 * @param values the elements to be removed
5353 * @return A new array containing the existing elements except the
5354 * earliest-encountered occurrences of the specified elements.
5355 * @since 3.0.1
5356 */
5357 public static byte[] removeElements(final byte[] array, final byte... values) {
5358 if (isEmpty(array) || isEmpty(values)) {
5359 return clone(array);
5360 }
5361 final Map<Byte, MutableInt> occurrences = new HashMap<Byte, MutableInt>(values.length);
5362 for (final byte v : values) {
5363 final Byte boxed = Byte.valueOf(v);
5364 final MutableInt count = occurrences.get(boxed);
5365 if (count == null) {
5366 occurrences.put(boxed, new MutableInt(1));
5367 } else {
5368 count.increment();
5369 }
5370 }
5371 final BitSet toRemove = new BitSet();
5372 for (final Map.Entry<Byte, MutableInt> e : occurrences.entrySet()) {
5373 final Byte v = e.getKey();
5374 int found = 0;
5375 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5376 found = indexOf(array, v.byteValue(), found);
5377 if (found < 0) {
5378 break;
5379 }
5380 toRemove.set(found++);
5381 }
5382 }
5383 return (byte[]) removeAll(array, toRemove);
5384 }
5385
5386 /**
5387 * <p>Removes the elements at the specified positions from the specified array.
5388 * All remaining elements are shifted to the left.</p>
5389 *
5390 * <p>This method returns a new array with the same elements of the input
5391 * array except those at the specified positions. The component
5392 * type of the returned array is always the same as that of the input
5393 * array.</p>
5394 *
5395 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5396 * will be thrown, because in that case no valid index can be specified.</p>
5397 *
5398 * <pre>
5399 * ArrayUtils.removeAll([1], 0) = []
5400 * ArrayUtils.removeAll([2, 6], 0) = [6]
5401 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5402 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5403 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5404 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5405 * </pre>
5406 *
5407 * @param array the array to remove the element from, may not be {@code null}
5408 * @param indices the positions of the elements to be removed
5409 * @return A new array containing the existing elements except those
5410 * at the specified positions.
5411 * @throws IndexOutOfBoundsException if any index is out of range
5412 * (index < 0 || index >= array.length), or if the array is {@code null}.
5413 * @since 3.0.1
5414 */
5415 public static short[] removeAll(final short[] array, final int... indices) {
5416 return (short[]) removeAll((Object) array, clone(indices));
5417 }
5418
5419 /**
5420 * <p>Removes occurrences of specified elements, in specified quantities,
5421 * from the specified array. All subsequent elements are shifted left.
5422 * For any element-to-be-removed specified in greater quantities than
5423 * contained in the original array, no change occurs beyond the
5424 * removal of the existing matching items.</p>
5425 *
5426 * <p>This method returns a new array with the same elements of the input
5427 * array except for the earliest-encountered occurrences of the specified
5428 * elements. The component type of the returned array is always the same
5429 * as that of the input array.</p>
5430 *
5431 * <pre>
5432 * ArrayUtils.removeElements(null, 1, 2) = null
5433 * ArrayUtils.removeElements([], 1, 2) = []
5434 * ArrayUtils.removeElements([1], 2, 3) = [1]
5435 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5436 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5437 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5438 * </pre>
5439 *
5440 * @param array the array to remove the element from, may be {@code null}
5441 * @param values the elements to be removed
5442 * @return A new array containing the existing elements except the
5443 * earliest-encountered occurrences of the specified elements.
5444 * @since 3.0.1
5445 */
5446 public static short[] removeElements(final short[] array, final short... values) {
5447 if (isEmpty(array) || isEmpty(values)) {
5448 return clone(array);
5449 }
5450 final HashMap<Short, MutableInt> occurrences = new HashMap<Short, MutableInt>(values.length);
5451 for (final short v : values) {
5452 final Short boxed = Short.valueOf(v);
5453 final MutableInt count = occurrences.get(boxed);
5454 if (count == null) {
5455 occurrences.put(boxed, new MutableInt(1));
5456 } else {
5457 count.increment();
5458 }
5459 }
5460 final BitSet toRemove = new BitSet();
5461 for (final Map.Entry<Short, MutableInt> e : occurrences.entrySet()) {
5462 final Short v = e.getKey();
5463 int found = 0;
5464 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5465 found = indexOf(array, v.shortValue(), found);
5466 if (found < 0) {
5467 break;
5468 }
5469 toRemove.set(found++);
5470 }
5471 }
5472 return (short[]) removeAll(array, toRemove);
5473 }
5474
5475 /**
5476 * <p>Removes the elements at the specified positions from the specified array.
5477 * All remaining elements are shifted to the left.</p>
5478 *
5479 * <p>This method returns a new array with the same elements of the input
5480 * array except those at the specified positions. The component
5481 * type of the returned array is always the same as that of the input
5482 * array.</p>
5483 *
5484 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5485 * will be thrown, because in that case no valid index can be specified.</p>
5486 *
5487 * <pre>
5488 * ArrayUtils.removeAll([1], 0) = []
5489 * ArrayUtils.removeAll([2, 6], 0) = [6]
5490 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5491 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5492 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5493 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5494 * </pre>
5495 *
5496 * @param array the array to remove the element from, may not be {@code null}
5497 * @param indices the positions of the elements to be removed
5498 * @return A new array containing the existing elements except those
5499 * at the specified positions.
5500 * @throws IndexOutOfBoundsException if any index is out of range
5501 * (index < 0 || index >= array.length), or if the array is {@code null}.
5502 * @since 3.0.1
5503 */
5504 public static int[] removeAll(final int[] array, final int... indices) {
5505 return (int[]) removeAll((Object) array, clone(indices));
5506 }
5507
5508 /**
5509 * <p>Removes occurrences of specified elements, in specified quantities,
5510 * from the specified array. All subsequent elements are shifted left.
5511 * For any element-to-be-removed specified in greater quantities than
5512 * contained in the original array, no change occurs beyond the
5513 * removal of the existing matching items.</p>
5514 *
5515 * <p>This method returns a new array with the same elements of the input
5516 * array except for the earliest-encountered occurrences of the specified
5517 * elements. The component type of the returned array is always the same
5518 * as that of the input array.</p>
5519 *
5520 * <pre>
5521 * ArrayUtils.removeElements(null, 1, 2) = null
5522 * ArrayUtils.removeElements([], 1, 2) = []
5523 * ArrayUtils.removeElements([1], 2, 3) = [1]
5524 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5525 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5526 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5527 * </pre>
5528 *
5529 * @param array the array to remove the element from, may be {@code null}
5530 * @param values the elements to be removed
5531 * @return A new array containing the existing elements except the
5532 * earliest-encountered occurrences of the specified elements.
5533 * @since 3.0.1
5534 */
5535 public static int[] removeElements(final int[] array, final int... values) {
5536 if (isEmpty(array) || isEmpty(values)) {
5537 return clone(array);
5538 }
5539 final HashMap<Integer, MutableInt> occurrences = new HashMap<Integer, MutableInt>(values.length);
5540 for (final int v : values) {
5541 final Integer boxed = Integer.valueOf(v);
5542 final MutableInt count = occurrences.get(boxed);
5543 if (count == null) {
5544 occurrences.put(boxed, new MutableInt(1));
5545 } else {
5546 count.increment();
5547 }
5548 }
5549 final BitSet toRemove = new BitSet();
5550 for (final Map.Entry<Integer, MutableInt> e : occurrences.entrySet()) {
5551 final Integer v = e.getKey();
5552 int found = 0;
5553 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5554 found = indexOf(array, v.intValue(), found);
5555 if (found < 0) {
5556 break;
5557 }
5558 toRemove.set(found++);
5559 }
5560 }
5561 return (int[]) removeAll(array, toRemove);
5562 }
5563
5564 /**
5565 * <p>Removes the elements at the specified positions from the specified array.
5566 * All remaining elements are shifted to the left.</p>
5567 *
5568 * <p>This method returns a new array with the same elements of the input
5569 * array except those at the specified positions. The component
5570 * type of the returned array is always the same as that of the input
5571 * array.</p>
5572 *
5573 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5574 * will be thrown, because in that case no valid index can be specified.</p>
5575 *
5576 * <pre>
5577 * ArrayUtils.removeAll([1], 0) = []
5578 * ArrayUtils.removeAll([2, 6], 0) = [6]
5579 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5580 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5581 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5582 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5583 * </pre>
5584 *
5585 * @param array the array to remove the element from, may not be {@code null}
5586 * @param indices the positions of the elements to be removed
5587 * @return A new array containing the existing elements except those
5588 * at the specified positions.
5589 * @throws IndexOutOfBoundsException if any index is out of range
5590 * (index < 0 || index >= array.length), or if the array is {@code null}.
5591 * @since 3.0.1
5592 */
5593 public static char[] removeAll(final char[] array, final int... indices) {
5594 return (char[]) removeAll((Object) array, clone(indices));
5595 }
5596
5597 /**
5598 * <p>Removes occurrences of specified elements, in specified quantities,
5599 * from the specified array. All subsequent elements are shifted left.
5600 * For any element-to-be-removed specified in greater quantities than
5601 * contained in the original array, no change occurs beyond the
5602 * removal of the existing matching items.</p>
5603 *
5604 * <p>This method returns a new array with the same elements of the input
5605 * array except for the earliest-encountered occurrences of the specified
5606 * elements. The component type of the returned array is always the same
5607 * as that of the input array.</p>
5608 *
5609 * <pre>
5610 * ArrayUtils.removeElements(null, 1, 2) = null
5611 * ArrayUtils.removeElements([], 1, 2) = []
5612 * ArrayUtils.removeElements([1], 2, 3) = [1]
5613 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5614 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5615 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5616 * </pre>
5617 *
5618 * @param array the array to remove the element from, may be {@code null}
5619 * @param values the elements to be removed
5620 * @return A new array containing the existing elements except the
5621 * earliest-encountered occurrences of the specified elements.
5622 * @since 3.0.1
5623 */
5624 public static char[] removeElements(final char[] array, final char... values) {
5625 if (isEmpty(array) || isEmpty(values)) {
5626 return clone(array);
5627 }
5628 final HashMap<Character, MutableInt> occurrences = new HashMap<Character, MutableInt>(values.length);
5629 for (final char v : values) {
5630 final Character boxed = Character.valueOf(v);
5631 final MutableInt count = occurrences.get(boxed);
5632 if (count == null) {
5633 occurrences.put(boxed, new MutableInt(1));
5634 } else {
5635 count.increment();
5636 }
5637 }
5638 final BitSet toRemove = new BitSet();
5639 for (final Map.Entry<Character, MutableInt> e : occurrences.entrySet()) {
5640 final Character v = e.getKey();
5641 int found = 0;
5642 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5643 found = indexOf(array, v.charValue(), found);
5644 if (found < 0) {
5645 break;
5646 }
5647 toRemove.set(found++);
5648 }
5649 }
5650 return (char[]) removeAll(array, toRemove);
5651 }
5652
5653 /**
5654 * <p>Removes the elements at the specified positions from the specified array.
5655 * All remaining elements are shifted to the left.</p>
5656 *
5657 * <p>This method returns a new array with the same elements of the input
5658 * array except those at the specified positions. The component
5659 * type of the returned array is always the same as that of the input
5660 * array.</p>
5661 *
5662 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5663 * will be thrown, because in that case no valid index can be specified.</p>
5664 *
5665 * <pre>
5666 * ArrayUtils.removeAll([1], 0) = []
5667 * ArrayUtils.removeAll([2, 6], 0) = [6]
5668 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5669 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5670 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5671 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5672 * </pre>
5673 *
5674 * @param array the array to remove the element from, may not be {@code null}
5675 * @param indices the positions of the elements to be removed
5676 * @return A new array containing the existing elements except those
5677 * at the specified positions.
5678 * @throws IndexOutOfBoundsException if any index is out of range
5679 * (index < 0 || index >= array.length), or if the array is {@code null}.
5680 * @since 3.0.1
5681 */
5682 public static long[] removeAll(final long[] array, final int... indices) {
5683 return (long[]) removeAll((Object) array, clone(indices));
5684 }
5685
5686 /**
5687 * <p>Removes occurrences of specified elements, in specified quantities,
5688 * from the specified array. All subsequent elements are shifted left.
5689 * For any element-to-be-removed specified in greater quantities than
5690 * contained in the original array, no change occurs beyond the
5691 * removal of the existing matching items.</p>
5692 *
5693 * <p>This method returns a new array with the same elements of the input
5694 * array except for the earliest-encountered occurrences of the specified
5695 * elements. The component type of the returned array is always the same
5696 * as that of the input array.</p>
5697 *
5698 * <pre>
5699 * ArrayUtils.removeElements(null, 1, 2) = null
5700 * ArrayUtils.removeElements([], 1, 2) = []
5701 * ArrayUtils.removeElements([1], 2, 3) = [1]
5702 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5703 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5704 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5705 * </pre>
5706 *
5707 * @param array the array to remove the element from, may be {@code null}
5708 * @param values the elements to be removed
5709 * @return A new array containing the existing elements except the
5710 * earliest-encountered occurrences of the specified elements.
5711 * @since 3.0.1
5712 */
5713 public static long[] removeElements(final long[] array, final long... values) {
5714 if (isEmpty(array) || isEmpty(values)) {
5715 return clone(array);
5716 }
5717 final HashMap<Long, MutableInt> occurrences = new HashMap<Long, MutableInt>(values.length);
5718 for (final long v : values) {
5719 final Long boxed = Long.valueOf(v);
5720 final MutableInt count = occurrences.get(boxed);
5721 if (count == null) {
5722 occurrences.put(boxed, new MutableInt(1));
5723 } else {
5724 count.increment();
5725 }
5726 }
5727 final BitSet toRemove = new BitSet();
5728 for (final Map.Entry<Long, MutableInt> e : occurrences.entrySet()) {
5729 final Long v = e.getKey();
5730 int found = 0;
5731 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5732 found = indexOf(array, v.longValue(), found);
5733 if (found < 0) {
5734 break;
5735 }
5736 toRemove.set(found++);
5737 }
5738 }
5739 return (long[]) removeAll(array, toRemove);
5740 }
5741
5742 /**
5743 * <p>Removes the elements at the specified positions from the specified array.
5744 * All remaining elements are shifted to the left.</p>
5745 *
5746 * <p>This method returns a new array with the same elements of the input
5747 * array except those at the specified positions. The component
5748 * type of the returned array is always the same as that of the input
5749 * array.</p>
5750 *
5751 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5752 * will be thrown, because in that case no valid index can be specified.</p>
5753 *
5754 * <pre>
5755 * ArrayUtils.removeAll([1], 0) = []
5756 * ArrayUtils.removeAll([2, 6], 0) = [6]
5757 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5758 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5759 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5760 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5761 * </pre>
5762 *
5763 * @param array the array to remove the element from, may not be {@code null}
5764 * @param indices the positions of the elements to be removed
5765 * @return A new array containing the existing elements except those
5766 * at the specified positions.
5767 * @throws IndexOutOfBoundsException if any index is out of range
5768 * (index < 0 || index >= array.length), or if the array is {@code null}.
5769 * @since 3.0.1
5770 */
5771 public static float[] removeAll(final float[] array, final int... indices) {
5772 return (float[]) removeAll((Object) array, clone(indices));
5773 }
5774
5775 /**
5776 * <p>Removes occurrences of specified elements, in specified quantities,
5777 * from the specified array. All subsequent elements are shifted left.
5778 * For any element-to-be-removed specified in greater quantities than
5779 * contained in the original array, no change occurs beyond the
5780 * removal of the existing matching items.</p>
5781 *
5782 * <p>This method returns a new array with the same elements of the input
5783 * array except for the earliest-encountered occurrences of the specified
5784 * elements. The component type of the returned array is always the same
5785 * as that of the input array.</p>
5786 *
5787 * <pre>
5788 * ArrayUtils.removeElements(null, 1, 2) = null
5789 * ArrayUtils.removeElements([], 1, 2) = []
5790 * ArrayUtils.removeElements([1], 2, 3) = [1]
5791 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5792 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5793 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5794 * </pre>
5795 *
5796 * @param array the array to remove the element from, may be {@code null}
5797 * @param values the elements to be removed
5798 * @return A new array containing the existing elements except the
5799 * earliest-encountered occurrences of the specified elements.
5800 * @since 3.0.1
5801 */
5802 public static float[] removeElements(final float[] array, final float... values) {
5803 if (isEmpty(array) || isEmpty(values)) {
5804 return clone(array);
5805 }
5806 final HashMap<Float, MutableInt> occurrences = new HashMap<Float, MutableInt>(values.length);
5807 for (final float v : values) {
5808 final Float boxed = Float.valueOf(v);
5809 final MutableInt count = occurrences.get(boxed);
5810 if (count == null) {
5811 occurrences.put(boxed, new MutableInt(1));
5812 } else {
5813 count.increment();
5814 }
5815 }
5816 final BitSet toRemove = new BitSet();
5817 for (final Map.Entry<Float, MutableInt> e : occurrences.entrySet()) {
5818 final Float v = e.getKey();
5819 int found = 0;
5820 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5821 found = indexOf(array, v.floatValue(), found);
5822 if (found < 0) {
5823 break;
5824 }
5825 toRemove.set(found++);
5826 }
5827 }
5828 return (float[]) removeAll(array, toRemove);
5829 }
5830
5831 /**
5832 * <p>Removes the elements at the specified positions from the specified array.
5833 * All remaining elements are shifted to the left.</p>
5834 *
5835 * <p>This method returns a new array with the same elements of the input
5836 * array except those at the specified positions. The component
5837 * type of the returned array is always the same as that of the input
5838 * array.</p>
5839 *
5840 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5841 * will be thrown, because in that case no valid index can be specified.</p>
5842 *
5843 * <pre>
5844 * ArrayUtils.removeAll([1], 0) = []
5845 * ArrayUtils.removeAll([2, 6], 0) = [6]
5846 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5847 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5848 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5849 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5850 * </pre>
5851 *
5852 * @param array the array to remove the element from, may not be {@code null}
5853 * @param indices the positions of the elements to be removed
5854 * @return A new array containing the existing elements except those
5855 * at the specified positions.
5856 * @throws IndexOutOfBoundsException if any index is out of range
5857 * (index < 0 || index >= array.length), or if the array is {@code null}.
5858 * @since 3.0.1
5859 */
5860 public static double[] removeAll(final double[] array, final int... indices) {
5861 return (double[]) removeAll((Object) array, clone(indices));
5862 }
5863
5864 /**
5865 * <p>Removes occurrences of specified elements, in specified quantities,
5866 * from the specified array. All subsequent elements are shifted left.
5867 * For any element-to-be-removed specified in greater quantities than
5868 * contained in the original array, no change occurs beyond the
5869 * removal of the existing matching items.</p>
5870 *
5871 * <p>This method returns a new array with the same elements of the input
5872 * array except for the earliest-encountered occurrences of the specified
5873 * elements. The component type of the returned array is always the same
5874 * as that of the input array.</p>
5875 *
5876 * <pre>
5877 * ArrayUtils.removeElements(null, 1, 2) = null
5878 * ArrayUtils.removeElements([], 1, 2) = []
5879 * ArrayUtils.removeElements([1], 2, 3) = [1]
5880 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5881 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5882 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5883 * </pre>
5884 *
5885 * @param array the array to remove the element from, may be {@code null}
5886 * @param values the elements to be removed
5887 * @return A new array containing the existing elements except the
5888 * earliest-encountered occurrences of the specified elements.
5889 * @since 3.0.1
5890 */
5891 public static double[] removeElements(final double[] array, final double... values) {
5892 if (isEmpty(array) || isEmpty(values)) {
5893 return clone(array);
5894 }
5895 final HashMap<Double, MutableInt> occurrences = new HashMap<Double, MutableInt>(values.length);
5896 for (final double v : values) {
5897 final Double boxed = Double.valueOf(v);
5898 final MutableInt count = occurrences.get(boxed);
5899 if (count == null) {
5900 occurrences.put(boxed, new MutableInt(1));
5901 } else {
5902 count.increment();
5903 }
5904 }
5905 final BitSet toRemove = new BitSet();
5906 for (final Map.Entry<Double, MutableInt> e : occurrences.entrySet()) {
5907 final Double v = e.getKey();
5908 int found = 0;
5909 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5910 found = indexOf(array, v.doubleValue(), found);
5911 if (found < 0) {
5912 break;
5913 }
5914 toRemove.set(found++);
5915 }
5916 }
5917 return (double[]) removeAll(array, toRemove);
5918 }
5919
5920 /**
5921 * <p>Removes the elements at the specified positions from the specified array.
5922 * All remaining elements are shifted to the left.</p>
5923 *
5924 * <p>This method returns a new array with the same elements of the input
5925 * array except those at the specified positions. The component
5926 * type of the returned array is always the same as that of the input
5927 * array.</p>
5928 *
5929 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5930 * will be thrown, because in that case no valid index can be specified.</p>
5931 *
5932 * <pre>
5933 * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
5934 * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
5935 * </pre>
5936 *
5937 * @param array the array to remove the element from, may not be {@code null}
5938 * @param indices the positions of the elements to be removed
5939 * @return A new array containing the existing elements except those
5940 * at the specified positions.
5941 * @throws IndexOutOfBoundsException if any index is out of range
5942 * (index < 0 || index >= array.length), or if the array is {@code null}.
5943 * @since 3.0.1
5944 */
5945 public static boolean[] removeAll(final boolean[] array, final int... indices) {
5946 return (boolean[]) removeAll((Object) array, clone(indices));
5947 }
5948
5949 /**
5950 * <p>Removes occurrences of specified elements, in specified quantities,
5951 * from the specified array. All subsequent elements are shifted left.
5952 * For any element-to-be-removed specified in greater quantities than
5953 * contained in the original array, no change occurs beyond the
5954 * removal of the existing matching items.</p>
5955 *
5956 * <p>This method returns a new array with the same elements of the input
5957 * array except for the earliest-encountered occurrences of the specified
5958 * elements. The component type of the returned array is always the same
5959 * as that of the input array.</p>
5960 *
5961 * <pre>
5962 * ArrayUtils.removeElements(null, true, false) = null
5963 * ArrayUtils.removeElements([], true, false) = []
5964 * ArrayUtils.removeElements([true], false, false) = [true]
5965 * ArrayUtils.removeElements([true, false], true, true) = [false]
5966 * ArrayUtils.removeElements([true, false, true], true) = [false, true]
5967 * ArrayUtils.removeElements([true, false, true], true, true) = [false]
5968 * </pre>
5969 *
5970 * @param array the array to remove the element from, may be {@code null}
5971 * @param values the elements to be removed
5972 * @return A new array containing the existing elements except the
5973 * earliest-encountered occurrences of the specified elements.
5974 * @since 3.0.1
5975 */
5976 public static boolean[] removeElements(final boolean[] array, final boolean... values) {
5977 if (isEmpty(array) || isEmpty(values)) {
5978 return clone(array);
5979 }
5980 final HashMap<Boolean, MutableInt> occurrences = new HashMap<Boolean, MutableInt>(2); // only two possible values here
5981 for (final boolean v : values) {
5982 final Boolean boxed = Boolean.valueOf(v);
5983 final MutableInt count = occurrences.get(boxed);
5984 if (count == null) {
5985 occurrences.put(boxed, new MutableInt(1));
5986 } else {
5987 count.increment();
5988 }
5989 }
5990 final BitSet toRemove = new BitSet();
5991 for (final Map.Entry<Boolean, MutableInt> e : occurrences.entrySet()) {
5992 final Boolean v = e.getKey();
5993 int found = 0;
5994 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5995 found = indexOf(array, v.booleanValue(), found);
5996 if (found < 0) {
5997 break;
5998 }
5999 toRemove.set(found++);
6000 }
6001 }
6002 return (boolean[]) removeAll(array, toRemove);
6003 }
6004
6005 /**
6006 * Removes multiple array elements specified by index.
6007 * @param array source
6008 * @param indices to remove, WILL BE SORTED--so only clones of user-owned arrays!
6009 * @return new array of same type minus elements specified by unique values of {@code indices}
6010 * @since 3.0.1
6011 */
6012 // package protected for access by unit tests
6013 static Object removeAll(final Object array, final int... indices) {
6014 final int length = getLength(array);
6015 int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
6016
6017 if (isNotEmpty(indices)) {
6018 Arrays.sort(indices);
6019
6020 int i = indices.length;
6021 int prevIndex = length;
6022 while (--i >= 0) {
6023 final int index = indices[i];
6024 if (index < 0 || index >= length) {
6025 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
6026 }
6027 if (index >= prevIndex) {
6028 continue;
6029 }
6030 diff++;
6031 prevIndex = index;
6032 }
6033 }
6034 final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
6035 if (diff < length) {
6036 int end = length; // index just after last copy
6037 int dest = length - diff; // number of entries so far not copied
6038 for (int i = indices.length - 1; i >= 0; i--) {
6039 final int index = indices[i];
6040 if (end - index > 1) { // same as (cp > 0)
6041 final int cp = end - index - 1;
6042 dest -= cp;
6043 System.arraycopy(array, index + 1, result, dest, cp);
6044 // Afer this copy, we still have room for dest items.
6045 }
6046 end = index;
6047 }
6048 if (end > 0) {
6049 System.arraycopy(array, 0, result, 0, end);
6050 }
6051 }
6052 return result;
6053 }
6054
6055 /**
6056 * Removes multiple array elements specified by indices.
6057 *
6058 * @param array source
6059 * @param indices to remove
6060 * @return new array of same type minus elements specified by the set bits in {@code indices}
6061 * @since 3.2
6062 */
6063 // package protected for access by unit tests
6064 static Object removeAll(final Object array, final BitSet indices) {
6065 final int srcLength = ArrayUtils.getLength(array);
6066 // No need to check maxIndex here, because method only currently called from removeElements()
6067 // which guarantee to generate on;y valid bit entries.
6068 // final int maxIndex = indices.length();
6069 // if (maxIndex > srcLength) {
6070 // throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
6071 // }
6072 final int removals = indices.cardinality(); // true bits are items to remove
6073 final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
6074 int srcIndex=0;
6075 int destIndex=0;
6076 int count;
6077 int set;
6078 while((set = indices.nextSetBit(srcIndex)) != -1){
6079 count = set - srcIndex;
6080 if (count > 0) {
6081 System.arraycopy(array, srcIndex, result, destIndex, count);
6082 destIndex += count;
6083 }
6084 srcIndex = indices.nextClearBit(set);
6085 }
6086 count = srcLength - srcIndex;
6087 if (count > 0) {
6088 System.arraycopy(array, srcIndex, result, destIndex, count);
6089 }
6090 return result;
6091 }
6092
6093 /**
6094 * <p>This method checks whether the provided array is sorted according to the class's
6095 * {@code compareTo} method.</p>
6096 *
6097 * @param array the array to check
6098 * @param <T> the datatype of the array to check, it must implement {@code Comparable}
6099 * @return whether the array is sorted
6100 * @since 3.4
6101 */
6102 public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
6103 return isSorted(array, new Comparator<T>() {
6104 @Override
6105 public int compare(T o1, T o2) {
6106 return o1.compareTo(o2);
6107 }
6108 });
6109 }
6110
6111
6112 /**
6113 * <p>This method checks whether the provided array is sorted according to the provided {@code Comparator}.</p>
6114 *
6115 * @param array the array to check
6116 * @param comparator the {@code Comparator} to compare over
6117 * @param <T> the datatype of the array
6118 * @return whether the array is sorted
6119 * @since 3.4
6120 */
6121 public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
6122 if (comparator == null) {
6123 throw new IllegalArgumentException("Comparator should not be null.");
6124 }
6125
6126 if(array == null || array.length < 2) {
6127 return true;
6128 }
6129
6130 T previous = array[0];
6131 final int n = array.length;
6132 for(int i = 1; i < n; i++) {
6133 final T current = array[i];
6134 if (comparator.compare(previous, current) > 0) {
6135 return false;
6136 }
6137
6138 previous = current;
6139 }
6140 return true;
6141 }
6142
6143 /**
6144 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6145 *
6146 * @param array the array to check
6147 * @return whether the array is sorted according to natural ordering
6148 * @since 3.4
6149 */
6150 public static boolean isSorted(int[] array) {
6151 if(array == null || array.length < 2) {
6152 return true;
6153 }
6154
6155 int previous = array[0];
6156 final int n = array.length;
6157 for(int i = 1; i < n; i++) {
6158 final int current = array[i];
6159 if(NumberUtils.compare(previous, current) > 0) {
6160 return false;
6161 }
6162
6163 previous = current;
6164 }
6165 return true;
6166 }
6167
6168 /**
6169 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6170 *
6171 * @param array the array to check
6172 * @return whether the array is sorted according to natural ordering
6173 * @since 3.4
6174 */
6175 public static boolean isSorted(long[] array) {
6176 if(array == null || array.length < 2) {
6177 return true;
6178 }
6179
6180 long previous = array[0];
6181 final int n = array.length;
6182 for(int i = 1; i < n; i++) {
6183 final long current = array[i];
6184 if(NumberUtils.compare(previous, current) > 0) {
6185 return false;
6186 }
6187
6188 previous = current;
6189 }
6190 return true;
6191 }
6192
6193 /**
6194 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6195 *
6196 * @param array the array to check
6197 * @return whether the array is sorted according to natural ordering
6198 * @since 3.4
6199 */
6200 public static boolean isSorted(short[] array) {
6201 if(array == null || array.length < 2) {
6202 return true;
6203 }
6204
6205 short previous = array[0];
6206 final int n = array.length;
6207 for(int i = 1; i < n; i++) {
6208 final short current = array[i];
6209 if(NumberUtils.compare(previous, current) > 0) {
6210 return false;
6211 }
6212
6213 previous = current;
6214 }
6215 return true;
6216 }
6217
6218 /**
6219 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6220 *
6221 * @param array the array to check
6222 * @return whether the array is sorted according to natural ordering
6223 * @since 3.4
6224 */
6225 public static boolean isSorted(final double[] array) {
6226 if(array == null || array.length < 2) {
6227 return true;
6228 }
6229
6230 double previous = array[0];
6231 final int n = array.length;
6232 for(int i = 1; i < n; i++) {
6233 final double current = array[i];
6234 if(Double.compare(previous, current) > 0) {
6235 return false;
6236 }
6237
6238 previous = current;
6239 }
6240 return true;
6241 }
6242
6243 /**
6244 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6245 *
6246 * @param array the array to check
6247 * @return whether the array is sorted according to natural ordering
6248 * @since 3.4
6249 */
6250 public static boolean isSorted(final float[] array) {
6251 if(array == null || array.length < 2) {
6252 return true;
6253 }
6254
6255 float previous = array[0];
6256 final int n = array.length;
6257 for(int i = 1; i < n; i++) {
6258 final float current = array[i];
6259 if(Float.compare(previous, current) > 0) {
6260 return false;
6261 }
6262
6263 previous = current;
6264 }
6265 return true;
6266 }
6267
6268 /**
6269 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6270 *
6271 * @param array the array to check
6272 * @return whether the array is sorted according to natural ordering
6273 * @since 3.4
6274 */
6275 public static boolean isSorted(byte[] array) {
6276 if(array == null || array.length < 2) {
6277 return true;
6278 }
6279
6280 byte previous = array[0];
6281 final int n = array.length;
6282 for(int i = 1; i < n; i++) {
6283 final byte current = array[i];
6284 if(NumberUtils.compare(previous, current) > 0) {
6285 return false;
6286 }
6287
6288 previous = current;
6289 }
6290 return true;
6291 }
6292
6293 /**
6294 * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
6295 *
6296 * @param array the array to check
6297 * @return whether the array is sorted according to natural ordering
6298 * @since 3.4
6299 */
6300 public static boolean isSorted(char[] array) {
6301 if(array == null || array.length < 2) {
6302 return true;
6303 }
6304
6305 char previous = array[0];
6306 final int n = array.length;
6307 for(int i = 1; i < n; i++) {
6308 final char current = array[i];
6309 if(CharUtils.compare(previous, current) > 0) {
6310 return false;
6311 }
6312
6313 previous = current;
6314 }
6315 return true;
6316 }
6317
6318 /**
6319 * <p>This method checks whether the provided array is sorted according to natural ordering
6320 * ({@code false} before {@code true}).</p>
6321 *
6322 * @param array the array to check
6323 * @return whether the array is sorted according to natural ordering
6324 * @since 3.4
6325 */
6326 public static boolean isSorted(boolean[] array) {
6327 if(array == null || array.length < 2) {
6328 return true;
6329 }
6330
6331 boolean previous = array[0];
6332 final int n = array.length;
6333 for(int i = 1; i < n; i++) {
6334 final boolean current = array[i];
6335 if(BooleanUtils.compare(previous, current) > 0) {
6336 return false;
6337 }
6338
6339 previous = current;
6340 }
6341 return true;
6342 }
6343 }